/// <summary> /// Revoke the CA signed certificate. /// The issuer CA public key, the private key and the crl reside in the storepath. /// The CRL number is increased by one and existing CRL for the issuer are deleted from the store. /// </summary> public static async Task <X509CRL> RevokeCertificateAsync( string storePath, X509Certificate2 certificate, string issuerKeyFilePassword = null ) { X509CRL updatedCRL = null; string subjectName = certificate.IssuerName.Name; string keyId = null; string serialNumber = null; // caller may want to create empty CRL using the CA cert itself bool isCACert = X509Utils.IsCertificateAuthority(certificate); // find the authority key identifier. X509AuthorityKeyIdentifierExtension authority = X509Extensions.FindExtension <X509AuthorityKeyIdentifierExtension>(certificate); if (authority != null) { keyId = authority.KeyIdentifier; serialNumber = authority.SerialNumber; } else { throw new ArgumentException("Certificate does not contain an Authority Key"); } if (!isCACert) { if (serialNumber == certificate.SerialNumber || X509Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer)) { throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Cannot revoke self signed certificates"); } } X509Certificate2 certCA = null; using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(storePath)) { if (store == null) { throw new ArgumentException("Invalid store path/type"); } certCA = await X509Utils.FindIssuerCABySerialNumberAsync(store, certificate.Issuer, serialNumber).ConfigureAwait(false); if (certCA == null) { throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Cannot find issuer certificate in store."); } if (!certCA.HasPrivateKey) { throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Issuer certificate has no private key, cannot revoke certificate."); } CertificateIdentifier certCAIdentifier = new CertificateIdentifier(certCA) { StorePath = storePath, StoreType = CertificateStoreIdentifier.DetermineStoreType(storePath) }; X509Certificate2 certCAWithPrivateKey = await certCAIdentifier.LoadPrivateKey(issuerKeyFilePassword).ConfigureAwait(false); if (certCAWithPrivateKey == null) { throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Failed to load issuer private key. Is the password correct?"); } List <X509CRL> certCACrl = store.EnumerateCRLs(certCA, false); var certificateCollection = new X509Certificate2Collection() { }; if (!isCACert) { certificateCollection.Add(certificate); } updatedCRL = CertificateFactory.RevokeCertificate(certCAWithPrivateKey, certCACrl, certificateCollection); store.AddCRL(updatedCRL); // delete outdated CRLs from store foreach (X509CRL caCrl in certCACrl) { store.DeleteCRL(caCrl); } store.Close(); } return(updatedCRL); }
/// <summary> /// Checks if the certicate meets the filter criteria. /// </summary> /// <param name="certificate">The certificate.</param> /// <returns>True if it meets the criteria.</returns> public bool Match(X509Certificate2 certificate) { if (certificate == null) { return(false); } try { if (!String.IsNullOrEmpty(m_subjectName)) { if (!Utils.Match(certificate.Subject, "CN*" + m_subjectName + ",*", false)) { return(false); } } if (!String.IsNullOrEmpty(m_issuerName)) { if (!Utils.Match(certificate.Issuer, "CN*" + m_issuerName + ",*", false)) { return(false); } } if (!String.IsNullOrEmpty(m_domain)) { IList <string> domains = X509Utils.GetDomainsFromCertficate(certificate); bool found = false; for (int ii = 0; ii < domains.Count; ii++) { if (Utils.Match(domains[ii], m_domain, false)) { found = true; break; } } if (!found) { return(false); } } // check for private key. if (m_privateKey) { if (!certificate.HasPrivateKey) { return(false); } } if (m_certificateTypes != null) { // determine if a CA certificate. bool isCA = X509Utils.IsCertificateAuthority(certificate); // determine if self-signed. bool isSelfSigned = X509Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer); // match if one or more of the criteria match. bool found = false; for (int ii = 0; ii < m_certificateTypes.Length; ii++) { switch (m_certificateTypes[ii]) { case CertificateListFilterType.Application: { if (!isCA) { found = true; } break; } case CertificateListFilterType.CA: { if (isCA) { found = true; } break; } case CertificateListFilterType.SelfSigned: { if (isSelfSigned) { found = true; } break; } case CertificateListFilterType.Issued: { if (!isSelfSigned) { found = true; } break; } } } if (!found) { return(false); } } return(true); } catch (Exception) { return(false); } }