private bool EraseStore(string storePath) { bool result = true; try { using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(storePath)) { var storeCerts = store.Enumerate().Result; foreach (var cert in storeCerts) { if (!store.Delete(cert.Thumbprint).Result) { result = false; } } var storeCrls = store.EnumerateCRLs(); foreach (var crl in storeCrls) { if (!store.DeleteCRL(crl)) { result = false; } } } } catch { result = false; } return(result); }
/// <summary> /// Updates the certificate authority certificate and CRL in the trusted list. /// </summary> private async Task UpdateAuthorityCertInTrustedList() { string trustedListStorePath = Configuration.TrustedListPath; if (!String.IsNullOrEmpty(Configuration.TrustedListPath)) { using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(trustedListStorePath)) { X509Certificate2Collection certs = await store.FindByThumbprint(Certificate.Thumbprint); if (certs.Count == 0) { await store.Add(Certificate); } // delete existing CRL in trusted list foreach (var crl in store.EnumerateCRLs(Certificate, false)) { if (crl.VerifySignature(Certificate, false)) { store.DeleteCRL(crl); } } // copy latest CRL to trusted list using (ICertificateStore storeAuthority = CertificateStoreIdentifier.OpenStore(m_authoritiesStorePath)) { foreach (var crl in storeAuthority.EnumerateCRLs(Certificate, true)) { store.AddCRL(crl); } } } } }
protected async Task UpdateGroupStore(string storePath, X509Certificate2Collection certs, IList <Opc.Ua.X509CRL> crls) { if (!String.IsNullOrEmpty(storePath)) { using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(storePath)) { X509Certificate2Collection oldCertificates = await store.Enumerate(); foreach (var cert in oldCertificates) { await store.Delete(cert.Thumbprint); } foreach (var crl in store.EnumerateCRLs()) { store.DeleteCRL(crl); } foreach (var cert in certs) { await store.Add(cert); } foreach (var crl in crls) { store.AddCRL(crl); } } } }
public static void CleanupTrustList(ICertificateStore store, bool dispose = true) { var certs = store.Enumerate().Result; foreach (var cert in certs) { store.Delete(cert.Thumbprint); } var crls = store.EnumerateCRLs(); foreach (var crl in crls) { store.DeleteCRL(crl); } if (dispose) { store.Dispose(); } }
/// <summary> /// Updates the certificate authority certificate and CRL in the trusted list. /// </summary> protected async Task UpdateAuthorityCertInTrustedList() { string trustedListStorePath = Configuration.TrustedListPath; if (!String.IsNullOrEmpty(Configuration.TrustedListPath)) { using (ICertificateStore authorityStore = CertificateStoreIdentifier.OpenStore(m_authoritiesStorePath)) using (ICertificateStore trustedStore = CertificateStoreIdentifier.OpenStore(trustedListStorePath)) { X509Certificate2Collection certificates = await authorityStore.Enumerate(); foreach (var certificate in certificates) { if (Utils.CompareDistinguishedName(certificate.Subject, m_subjectName)) { X509Certificate2Collection certs = await trustedStore.FindByThumbprint(certificate.Thumbprint); if (certs.Count == 0) { await trustedStore.Add(new X509Certificate2(certificate.RawData)); } // delete existing CRL in trusted list foreach (var crl in trustedStore.EnumerateCRLs(certificate, false)) { if (crl.VerifySignature(certificate, false)) { trustedStore.DeleteCRL(crl); } } // copy latest CRL to trusted list foreach (var crl in authorityStore.EnumerateCRLs(certificate, true)) { trustedStore.AddCRL(crl); } } } } } }
private async Task <bool> UpdateStoreCrls( CertificateTrustList trustList, X509CRLCollection updatedCrls) { bool result = true; ICertificateStore store = null; try { store = trustList.OpenStore(); var storeCrls = await store.EnumerateCRLs().ConfigureAwait(false); foreach (var crl in storeCrls) { if (!updatedCrls.Contains(crl)) { if (!await store.DeleteCRL(crl).ConfigureAwait(false)) { result = false; } } else { updatedCrls.Remove(crl); } } foreach (var crl in updatedCrls) { await store.AddCRL(crl).ConfigureAwait(false); } } catch { result = false; } finally { store?.Close(); } return(result); }
private async Task <bool> UpdateStoreCrls( string storePath, X509CRLCollection updatedCrls) { bool result = true; try { using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(storePath)) { var storeCrls = await store.EnumerateCRLs().ConfigureAwait(false); foreach (var crl in storeCrls) { if (!updatedCrls.Contains(crl)) { if (!await store.DeleteCRL(crl).ConfigureAwait(false)) { result = false; } } else { updatedCrls.Remove(crl); } } foreach (var crl in updatedCrls) { await store.AddCRL(crl).ConfigureAwait(false); } } } catch { result = false; } return(result); }
private bool UpdateStoreCrls( string storePath, IList <X509CRL> updatedCrls) { bool result = true; try { using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(storePath)) { var storeCrls = store.EnumerateCRLs(); foreach (var crl in storeCrls) { if (!updatedCrls.Contains(crl)) { if (!store.DeleteCRL(crl)) { result = false; } } else { updatedCrls.Remove(crl); } } foreach (var crl in updatedCrls) { store.AddCRL(crl); } } } catch { result = false; } return(result); }
private ServiceResult RemoveCertificate( ISystemContext context, MethodState method, NodeId objectId, string thumbprint, bool isTrustedCertificate) { HasSecureWriteAccess(context); lock (m_lock) { if (m_sessionId != null) { return(StatusCodes.BadInvalidState); } if (String.IsNullOrEmpty(thumbprint)) { return(StatusCodes.BadInvalidArgument); } using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(isTrustedCertificate ? m_trustedStorePath : m_issuerStorePath)) { var certCollection = store.FindByThumbprint(thumbprint).Result; if (certCollection.Count == 0) { return(StatusCodes.BadInvalidArgument); } // delete all CRLs signed by cert var crlsToDelete = new List <X509CRL>(); foreach (var crl in store.EnumerateCRLs()) { foreach (var cert in certCollection) { if (X509Utils.CompareDistinguishedName(cert.Subject, crl.Issuer) && crl.VerifySignature(cert, false)) { crlsToDelete.Add(crl); break; } } } if (!store.Delete(thumbprint).Result) { return(StatusCodes.BadInvalidArgument); } foreach (var crl in crlsToDelete) { if (!store.DeleteCRL(crl)) { // intentionally ignore errors, try best effort Utils.Trace("RemoveCertificate: Failed to delete CRL {0}.", crl.ToString()); } } } m_node.LastUpdateTime.Value = DateTime.UtcNow; } return(ServiceResult.Good); }
/// <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; try { 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 = IsCertificateAuthority(certificate); // find the authority key identifier. X509AuthorityKeyIdentifierExtension authority = FindAuthorityKeyIdentifier(certificate); if (authority != null) { keyId = authority.KeyId; serialNumber = authority.SerialNumber; } else { throw new ArgumentException("Certificate does not contain an Authority Key"); } if (!isCACert) { if (serialNumber == certificate.SerialNumber || Utils.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 FindIssuerCABySerialNumberAsync(store, certificate.Issuer, serialNumber); 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); certCAIdentifier.StorePath = storePath; certCAIdentifier.StoreType = CertificateStoreIdentifier.DetermineStoreType(storePath); X509Certificate2 certCAWithPrivateKey = await certCAIdentifier.LoadPrivateKey(issuerKeyFilePassword); 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); using (var cfrg = new CertificateFactoryRandomGenerator()) { // cert generators SecureRandom random = new SecureRandom(cfrg); BigInteger crlSerialNumber = BigInteger.Zero; Org.BouncyCastle.X509.X509Certificate bcCertCA = new X509CertificateParser().ReadCertificate(certCA.RawData); AsymmetricKeyParameter signingKey = GetPrivateKeyParameter(certCAWithPrivateKey); ISignatureFactory signatureFactory = new Asn1SignatureFactory(GetRSAHashAlgorithm(defaultHashSize), signingKey, random); X509V2CrlGenerator crlGen = new X509V2CrlGenerator(); crlGen.SetIssuerDN(bcCertCA.IssuerDN); crlGen.SetThisUpdate(DateTime.UtcNow); crlGen.SetNextUpdate(DateTime.UtcNow.AddMonths(12)); // merge all existing revocation list X509CrlParser parser = new X509CrlParser(); foreach (X509CRL caCrl in certCACrl) { X509Crl crl = parser.ReadCrl(caCrl.RawData); crlGen.AddCrl(crl); var crlVersion = GetCrlNumber(crl); if (crlVersion.IntValue > crlSerialNumber.IntValue) { crlSerialNumber = crlVersion; } } if (isCACert) { // add a dummy revoked cert crlGen.AddCrlEntry(BigInteger.One, DateTime.UtcNow, CrlReason.Superseded); } else { // add the revoked cert crlGen.AddCrlEntry(GetSerialNumber(certificate), DateTime.UtcNow, CrlReason.PrivilegeWithdrawn); } crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(bcCertCA)); // set new serial number crlSerialNumber = crlSerialNumber.Add(BigInteger.One); crlGen.AddExtension(X509Extensions.CrlNumber, false, new CrlNumber(crlSerialNumber)); // generate updated CRL X509Crl updatedCrl = crlGen.Generate(signatureFactory); // add updated CRL to store updatedCRL = new X509CRL(updatedCrl.GetEncoded()); store.AddCRL(updatedCRL); // delete outdated CRLs from store foreach (X509CRL caCrl in certCACrl) { store.DeleteCRL(caCrl); } } store.Close(); } } catch (Exception e) { throw e; } return(updatedCRL); }
/// <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); }
private ServiceResult RemoveCertificate( ISystemContext context, MethodState method, NodeId objectId, string thumbprint, bool isTrustedCertificate) { HasSecureWriteAccess(context); ServiceResult result = StatusCodes.Good; lock (m_lock) { if (m_sessionId != null) { result = StatusCodes.BadInvalidState; } else if (String.IsNullOrEmpty(thumbprint)) { result = StatusCodes.BadInvalidArgument; } else { using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(isTrustedCertificate ? m_trustedStorePath : m_issuerStorePath)) { var certCollection = store.FindByThumbprint(thumbprint).GetAwaiter().GetResult(); if (certCollection.Count == 0) { result = StatusCodes.BadInvalidArgument; } else { // delete all CRLs signed by cert var crlsToDelete = new X509CRLCollection(); foreach (var crl in store.EnumerateCRLs().GetAwaiter().GetResult()) { foreach (var cert in certCollection) { if (X509Utils.CompareDistinguishedName(cert.SubjectName, crl.IssuerName) && crl.VerifySignature(cert, false)) { crlsToDelete.Add(crl); break; } } } if (!store.Delete(thumbprint).GetAwaiter().GetResult()) { result = StatusCodes.BadInvalidArgument; } else { foreach (var crl in crlsToDelete) { if (!store.DeleteCRL(crl).GetAwaiter().GetResult()) { // intentionally ignore errors, try best effort Utils.LogError("RemoveCertificate: Failed to delete CRL {0}.", crl.ToString()); } } } } } m_node.LastUpdateTime.Value = DateTime.UtcNow; } } // report the TrustListUpdatedAuditEvent object[] inputParameters = new object[] { thumbprint }; m_node.ReportTrustListUpdatedAuditEvent(context, objectId, "Method/RemoveCertificate", method.NodeId, inputParameters, result.StatusCode); return(result); }
public override async Task Init() { Utils.Trace(Utils.TraceMasks.Information, "InitializeCertificateGroup: {0}", m_subjectName); X509Certificate2Collection rootCACertificateChain; IList <Opc.Ua.X509CRL> rootCACrlChain; try { // read root CA chain for certificate group rootCACertificateChain = await _opcVaultHandler.GetCACertificateChainAsync(Configuration.Id).ConfigureAwait(false); rootCACrlChain = await _opcVaultHandler.GetCACrlChainAsync(Configuration.Id).ConfigureAwait(false); var rootCaCert = rootCACertificateChain[0]; var rootCaCrl = rootCACrlChain[0]; if (Utils.CompareDistinguishedName(rootCaCert.Subject, m_subjectName)) { Certificate = rootCaCert; rootCaCrl.VerifySignature(rootCaCert, true); } else { throw new ServiceResultException("Key Vault certificate subject(" + rootCaCert.Subject + ") does not match cert group subject " + m_subjectName); } } catch (Exception ex) { Utils.Trace("Failed to load CA certificate " + Configuration.Id + " from key Vault "); Utils.Trace(ex.Message); throw ex; } // add all existing cert versions to trust list // erase old certs using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_authoritiesStorePath)) { try { X509Certificate2Collection certificates = await store.Enumerate(); foreach (var certificate in certificates) { // TODO: Subject may have changed over time if (Utils.CompareDistinguishedName(certificate.Subject, m_subjectName)) { var certs = rootCACertificateChain.Find(X509FindType.FindByThumbprint, certificate.Thumbprint, false); if (certs == null || certs.Count == 0) { Utils.Trace("Delete CA certificate from authority store: " + certificate.Thumbprint); // delete existing CRL in trusted list foreach (var crl in store.EnumerateCRLs(certificate, false)) { if (crl.VerifySignature(certificate, false)) { store.DeleteCRL(crl); } } await store.Delete(certificate.Thumbprint); } } } } catch (Exception ex) { Utils.Trace("Failed to Delete existing certificates from authority store: " + ex.Message); } foreach (var rootCACertificate in rootCACertificateChain) { X509Certificate2Collection certs = await store.FindByThumbprint(rootCACertificate.Thumbprint); if (certs.Count == 0) { await store.Add(rootCACertificate); Utils.Trace("Added CA certificate to authority store: " + rootCACertificate.Thumbprint); } else { Utils.Trace("CA certificate already exists in authority store: " + rootCACertificate.Thumbprint); } foreach (var rootCACrl in rootCACrlChain) { if (rootCACrl.VerifySignature(rootCACertificate, false)) { // delete existing CRL in trusted list foreach (var crl in store.EnumerateCRLs(rootCACertificate, false)) { if (crl.VerifySignature(rootCACertificate, false)) { store.DeleteCRL(crl); } } store.AddCRL(rootCACrl); } } } // load trust list from server var trustList = await _opcVaultHandler.GetTrustListAsync(Configuration.Id).ConfigureAwait(false); await UpdateTrustList(trustList); } }