Ejemplo n.º 1
0
        /// <summary>
        /// In case of delta CRL this function will return the delta CRL location.
        /// </summary>
        /// <param name="stCrlInfo"> win32 CRL INFO</param>
        /// <returns>URL for CRL</returns>
        private string GetDeltaCrlUrl(WinCrypt32.CRL_INFO stCrlInfo)
        {
            IntPtr        rgExtension       = stCrlInfo.rgExtension;
            X509Extension deltaCrlExtension = null;

            for (int i = 0; i < stCrlInfo.cExtension; i++)
            {
                WinCrypt32.CERT_EXTENSION stCrlExt = (WinCrypt32.CERT_EXTENSION)Marshal.PtrToStructure(rgExtension, typeof(WinCrypt32.CERT_EXTENSION));

                if (stCrlExt.Value.pbData != IntPtr.Zero && stCrlExt.pszObjId == CRL_FRESH_DELTA_OID)
                {
                    byte[] rawData = new byte[stCrlExt.Value.cbData];
                    Marshal.Copy(stCrlExt.Value.pbData, rawData, 0, rawData.Length);
                    deltaCrlExtension = new X509Extension(stCrlExt.pszObjId, rawData, stCrlExt.fCritical);
                    break;
                }

                rgExtension = (IntPtr)((Int32)rgExtension + Marshal.SizeOf(typeof(WinCrypt32.CERT_EXTENSION)));
            }
            if (deltaCrlExtension == null)
            {
                return(null);
            }
            return(GetCrlUrlFromExtension(deltaCrlExtension));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Checks if the Certificate is in the specific CRL list
        /// </summary>
        /// <param name="cert">Certificate</param>
        /// <param name="stCrlInfo">CRL structure ASN.1</param>
        /// <returns>true in case of certificate is in the revocation list</returns>
        private bool IsCertificateInCrl(X509Certificate2 cert, WinCrypt32.CRL_INFO stCrlInfo)
        {
            IntPtr rgCrlEntry = stCrlInfo.rgCRLEntry;

            for (int i = 0; i < stCrlInfo.cCRLEntry; i++)
            {
                string serial = string.Empty;
                WinCrypt32.CRL_ENTRY stCrlEntry = (WinCrypt32.CRL_ENTRY)Marshal.PtrToStructure(rgCrlEntry, typeof(WinCrypt32.CRL_ENTRY));

                IntPtr pByte = stCrlEntry.SerialNumber.pbData;
                for (int j = 0; j < stCrlEntry.SerialNumber.cbData; j++)
                {
                    Byte bByte = Marshal.ReadByte(pByte);
                    serial = bByte.ToString("X").PadLeft(2, '0') + serial;
                    pByte  = (IntPtr)((Int32)pByte + Marshal.SizeOf(typeof(Byte)));
                }
                if (cert.SerialNumber == serial)
                {
                    return(true);
                }
                rgCrlEntry = (IntPtr)((Int32)rgCrlEntry + Marshal.SizeOf(typeof(WinCrypt32.CRL_ENTRY)));
            }
            return(false);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// can be used to check if the certificate is available in a specific File for CRL.
        /// </summary>
        /// <param name="cert"></param>
        /// <param name="CRLFilePath"></param>
        /// <returns></returns>
        internal bool IsCertificateInCrlFile(X509Certificate2 cert, string CRLFilePath)
        {
            CRLData = File.ReadAllBytes(CRLFilePath);
            if (!CheckCRLMessageSignature(CRLData))
            {
                return(false);
            }

            IntPtr   phCertStore = IntPtr.Zero;
            IntPtr   pvContext   = IntPtr.Zero;
            GCHandle hCrlData    = new GCHandle();
            GCHandle hCryptBlob  = new GCHandle();

            try
            {
                hCrlData = GCHandle.Alloc(CRLData, GCHandleType.Pinned);
                WinCrypt32.CRYPTOAPI_BLOB stCryptBlob;
                stCryptBlob.cbData = CRLData.Length;
                stCryptBlob.pbData = hCrlData.AddrOfPinnedObject();
                hCryptBlob         = GCHandle.Alloc(stCryptBlob, GCHandleType.Pinned);

                if (!WinCrypt32.CryptQueryObject(
                        WinCrypt32.CERT_QUERY_OBJECT_BLOB,
                        hCryptBlob.AddrOfPinnedObject(),
                        WinCrypt32.CERT_QUERY_CONTENT_FLAG_CRL,
                        WinCrypt32.CERT_QUERY_FORMAT_FLAG_BINARY,
                        0,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        ref phCertStore,
                        IntPtr.Zero,
                        ref pvContext
                        ))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                WinCrypt32.CRL_CONTEXT stCrlContext = (WinCrypt32.CRL_CONTEXT)Marshal.PtrToStructure(pvContext, typeof(WinCrypt32.CRL_CONTEXT));
                WinCrypt32.CRL_INFO    stCrlInfo    = (WinCrypt32.CRL_INFO)Marshal.PtrToStructure(stCrlContext.pCrlInfo, typeof(WinCrypt32.CRL_INFO));

                CRLNextUpdate = WinCrypt32.FiletimeToDateTime(stCrlInfo.NextUpdate);
                if (CRLNextUpdate < DateTime.Now)
                {
                    throw new CRLExpection("CRL has expired");
                }

                if (IsCertificateInCrl(cert, stCrlInfo))
                {
                    return(true);
                }
            }
            finally
            {
                if (hCrlData.IsAllocated)
                {
                    hCrlData.Free();
                }
                if (hCryptBlob.IsAllocated)
                {
                    hCryptBlob.Free();
                }
                if (!pvContext.Equals(IntPtr.Zero))
                {
                    WinCrypt32.CertFreeCRLContext(pvContext);
                }
            }

            return(false);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// can be used to check if the certificate is available in a specific URL for CRL. A proxy can be optionally used.
        /// </summary>
        /// <param name="cert"></param>
        /// <param name="url"></param>
        /// <param name="proxy"></param>
        /// <returns></returns>
        internal bool IsCertificateInOnlineCRL(X509Certificate2 cert, string url, WebProxy proxy = null)
        {
            if (CRLNextUpdate < DateTime.Now /* is CRLNextupdate expired*/ || CRLDownloadedExpiry < DateTime.Now /*is Downloaded CRL expired*/)//check if locally cached CRL is still valid.
            {
                WebClient wc = new WebClient();
                if (proxy != null)
                {
                    wc.Proxy = proxy;
                }
                CRLData             = wc.DownloadData(url);
                CRLDownloadedExpiry = DateTime.Now.AddHours(1);
            }

            if (!CheckCRLMessageSignature(CRLData))
            {
                return(false);
            }

            IntPtr   phCertStore = IntPtr.Zero;
            IntPtr   pvContext   = IntPtr.Zero;
            GCHandle hCrlData    = new GCHandle();
            GCHandle hCryptBlob  = new GCHandle();

            try
            {
                hCrlData = GCHandle.Alloc(CRLData, GCHandleType.Pinned);
                WinCrypt32.CRYPTOAPI_BLOB stCryptBlob;
                stCryptBlob.cbData = CRLData.Length;
                stCryptBlob.pbData = hCrlData.AddrOfPinnedObject();
                hCryptBlob         = GCHandle.Alloc(stCryptBlob, GCHandleType.Pinned);

                if (!WinCrypt32.CryptQueryObject(
                        WinCrypt32.CERT_QUERY_OBJECT_BLOB,
                        hCryptBlob.AddrOfPinnedObject(),
                        WinCrypt32.CERT_QUERY_CONTENT_FLAG_CRL,
                        WinCrypt32.CERT_QUERY_FORMAT_FLAG_BINARY,
                        0,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        ref phCertStore,
                        IntPtr.Zero,
                        ref pvContext
                        ))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                WinCrypt32.CRL_CONTEXT stCrlContext = (WinCrypt32.CRL_CONTEXT)Marshal.PtrToStructure(pvContext, typeof(WinCrypt32.CRL_CONTEXT));
                WinCrypt32.CRL_INFO    stCrlInfo    = (WinCrypt32.CRL_INFO)Marshal.PtrToStructure(stCrlContext.pCrlInfo, typeof(WinCrypt32.CRL_INFO));

                CRLNextUpdate = WinCrypt32.FiletimeToDateTime(stCrlInfo.NextUpdate);

                if (CRLNextUpdate < DateTime.Now)
                {
                    throw new CRLExpection("CRL has expired");
                }

                if (IsCertificateInCrl(cert, stCrlInfo))
                {
                    return(true);
                }
                else
                {
                    url = GetDeltaCrlUrl(stCrlInfo);
                    if (!string.IsNullOrEmpty(url))
                    {
                        return(IsCertificateInOnlineCRL(cert, url));
                    }
                }
            }
            finally
            {
                if (hCrlData.IsAllocated)
                {
                    hCrlData.Free();
                }
                if (hCryptBlob.IsAllocated)
                {
                    hCryptBlob.Free();
                }
                if (!pvContext.Equals(IntPtr.Zero))
                {
                    WinCrypt32.CertFreeCRLContext(pvContext);
                }
            }

            return(false);
        }