/// <summary> /// Verifies the signature on the CRL. /// </summary> public bool VerifySignature(X509Certificate2 issuer, bool throwOnError) { Win32.CERT_CONTEXT context = (Win32.CERT_CONTEXT)Marshal.PtrToStructure(issuer.Handle, typeof(Win32.CERT_CONTEXT)); Win32.CERT_INFO info = (Win32.CERT_INFO)Marshal.PtrToStructure(context.pCertInfo, typeof(Win32.CERT_INFO)); int bResult = Win32.CryptVerifyCertificateSignature( IntPtr.Zero, Win32.X509_ASN_ENCODING, m_pBuffer, m_bufferSize, ref info.SubjectPublicKeyInfo); if (bResult == 0) { if (throwOnError) { throw Win32.GetLastError(StatusCodes.BadCertificateInvalid, "Could not get verify signature on CRL."); } return(false); } m_issuer = issuer; return(true); }
/// <summary> /// Returns true the certificate is in the CRL. /// </summary> public bool IsRevoked(X509Certificate2 certificate) { IntPtr pData1 = IntPtr.Zero; IntPtr pData2 = IntPtr.Zero; int dwDataSize1 = 0; try { // check that the issuer matches. if (m_issuer == null || !Utils.CompareDistinguishedName(certificate.Issuer, m_issuer.Subject)) { throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Certificate was not created by the CRL issuer."); } // get the cert info for the target certificate. Win32.CERT_CONTEXT context = (Win32.CERT_CONTEXT)Marshal.PtrToStructure(certificate.Handle, typeof(Win32.CERT_CONTEXT)); // calculate amount of memory required. int bResult = Win32.CryptDecodeObjectEx( Win32.X509_ASN_ENCODING | Win32.PKCS_7_ASN_ENCODING, (IntPtr)Win32.X509_CERT_CRL_TO_BE_SIGNED, m_signedCrl.ToBeSigned.pbData, m_signedCrl.ToBeSigned.cbData, Win32.CRYPT_DECODE_NOCOPY_FLAG, IntPtr.Zero, pData1, ref dwDataSize1); if (bResult == 0) { throw Win32.GetLastError(StatusCodes.BadDecodingError, "Could not get size for CRL_INFO."); } // allocate memory. pData1 = Marshal.AllocHGlobal(dwDataSize1); // decode blob. bResult = Win32.CryptDecodeObjectEx( Win32.X509_ASN_ENCODING | Win32.PKCS_7_ASN_ENCODING, (IntPtr)Win32.X509_CERT_CRL_TO_BE_SIGNED, m_signedCrl.ToBeSigned.pbData, m_signedCrl.ToBeSigned.cbData, Win32.CRYPT_DECODE_NOCOPY_FLAG, IntPtr.Zero, pData1, ref dwDataSize1); if (bResult == 0) { throw Win32.GetLastError(StatusCodes.BadDecodingError, "Could not decode CRL_INFO."); } IntPtr[] pCRLs = new IntPtr[] { pData1 }; pData2 = Marshal.AllocHGlobal(IntPtr.Size * pCRLs.Length); Marshal.Copy(pCRLs, 0, pData2, pCRLs.Length); // check for revocation. bResult = Win32.CertVerifyCRLRevocation( Win32.X509_ASN_ENCODING | Win32.PKCS_7_ASN_ENCODING, context.pCertInfo, pCRLs.Length, pData2); if (bResult == 0) { return(true); } // not revoked. return(false); } finally { if (pData1 != IntPtr.Zero) { Marshal.FreeHGlobal(pData1); pData1 = IntPtr.Zero; } if (pData2 != IntPtr.Zero) { Marshal.FreeHGlobal(pData2); pData2 = IntPtr.Zero; } } }