/// <summary> /// Saves the certificate in the rejected certificate store. /// </summary> private void SaveCertificate(X509Certificate2 certificate) { lock (m_lock) { if (m_rejectedCertificateStore != null) { Utils.Trace((int)Utils.TraceMasks.Error, "Writing rejected certificate to directory: {0}", m_rejectedCertificateStore); try { ICertificateStore store = m_rejectedCertificateStore.OpenStore(); try { store.Delete(certificate.Thumbprint); store.Add(certificate); } finally { store.Close(); } } catch (Exception e) { Utils.Trace(e, "Could not write certificate to directory: {0}", m_rejectedCertificateStore); } } } }
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); }
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); } } } }
/// <summary> /// Deletes an existing application instance certificate. /// </summary> /// <param name="configuration">The configuration instance that stores the configurable information for a UA application.</param> private static async Task DeleteApplicationInstanceCertificate(ApplicationConfiguration configuration) { // create a default certificate id none specified. CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate; if (id == null) { return; } // delete certificate and private key. X509Certificate2 certificate = await id.Find().ConfigureAwait(false); if (certificate != null) { Utils.LogCertificate(TraceMasks.Security, "Deleting application instance certificate and private key.", certificate); } // delete trusted peer certificate. if (configuration.SecurityConfiguration != null && configuration.SecurityConfiguration.TrustedPeerCertificates != null) { string thumbprint = id.Thumbprint; if (certificate != null) { thumbprint = certificate.Thumbprint; } if (!string.IsNullOrEmpty(thumbprint)) { using (ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore()) { bool deleted = await store.Delete(thumbprint).ConfigureAwait(false); if (deleted) { Utils.LogInfo(TraceMasks.Security, "Application Instance Certificate [{0}] deleted from trusted store.", thumbprint); } } } } // delete certificate and private key from owner store. if (certificate != null) { using (ICertificateStore store = id.OpenStore()) { bool deleted = await store.Delete(certificate.Thumbprint).ConfigureAwait(false); if (deleted) { Utils.LogCertificate(TraceMasks.Security, "Application certificate and private key deleted.", certificate); } } } // erase the memory copy of the deleted certificate id.Certificate = null; }
/// <summary> /// Adds an application certificate to a store. /// </summary> private static void AddApplicationCertificateToStore( CertificateStoreIdentifier csid, X509Certificate2 certificate, string oldThumbprint) { ICertificateStore store = csid.OpenStore(); try { // delete the old certificate. if (oldThumbprint != null) { store.Delete(oldThumbprint); } // delete certificates with the same application uri. if (store.FindByThumbprint(certificate.Thumbprint) != null) { return; } string applicationUri = Utils.GetApplicationUriFromCertficate(certificate); // delete any existing certificates. foreach (X509Certificate2 target in store.Enumerate()) { if (!Utils.CompareDistinguishedName(target.Subject, certificate.Subject)) { continue; } if (Utils.GetApplicationUriFromCertficate(target) == applicationUri) { store.Delete(target.Thumbprint); } } // add new certificate. store.Add(new X509Certificate2(certificate.RawData)); } finally { store.Close(); } }
public async Task TestNoFileConfigAsServerX509Store() { #if NETCOREAPP2_1_OR_GREATER // this test fails on macOS, ignore if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { Assert.Ignore("X509Store trust lists not supported on mac OS."); } #endif var applicationInstance = new ApplicationInstance() { ApplicationName = ApplicationName }; Assert.NotNull(applicationInstance); ApplicationConfiguration config = await applicationInstance.Build(ApplicationUri, ProductUri) .AsServer(new string[] { EndpointUrl }) .AddUnsecurePolicyNone() .AddSignAndEncryptPolicies() .AddUserTokenPolicy(UserTokenType.UserName) .AsClient() .SetDefaultSessionTimeout(10000) .AddSecurityConfiguration(SubjectName, CertificateStoreType.X509Store) .Create().ConfigureAwait(false); Assert.NotNull(config); var applicationCertificate = applicationInstance.ApplicationConfiguration.SecurityConfiguration.ApplicationCertificate; bool deleteAfterUse = applicationCertificate.Certificate != null; bool certOK = await applicationInstance.CheckApplicationInstanceCertificate(true, 0).ConfigureAwait(false); Assert.True(certOK); using (ICertificateStore store = applicationInstance.ApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.OpenStore()) { // store public key in trusted store var rawData = applicationCertificate.Certificate.RawData; await store.Add(new X509Certificate2(rawData)); } if (deleteAfterUse) { var thumbprint = applicationCertificate.Certificate.Thumbprint; using (ICertificateStore store = applicationCertificate.OpenStore()) { bool success = await store.Delete(thumbprint); Assert.IsTrue(success); } using (ICertificateStore store = applicationInstance.ApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.OpenStore()) { bool success = await store.Delete(thumbprint); Assert.IsTrue(success); } } }
private async void DeleteExistingFromStore(string storePath) { if (String.IsNullOrEmpty(storePath)) { return; } using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(storePath)) { X509Certificate2Collection certificates = await store.Enumerate(); foreach (var certificate in certificates) { if (store.GetPrivateKeyFilePath(certificate.Thumbprint) != null) { continue; } List <string> fields = Utils.ParseDistinguishedName(certificate.Subject); if (fields.Contains("CN=UA Local Discovery Server")) { continue; } DirectoryCertificateStore ds = store as DirectoryCertificateStore; if (ds != null) { string path = Utils.GetAbsoluteFilePath(m_application.CertificatePublicKeyPath, true, false, false); if (path != null) { if (String.Compare(path, ds.GetPublicKeyFilePath(certificate.Thumbprint), StringComparison.OrdinalIgnoreCase) == 0) { continue; } } path = Utils.GetAbsoluteFilePath(m_application.CertificatePrivateKeyPath, true, false, false); if (path != null) { if (String.Compare(path, ds.GetPrivateKeyFilePath(certificate.Thumbprint), StringComparison.OrdinalIgnoreCase) == 0) { continue; } } } await store.Delete(certificate.Thumbprint); } } }
/// <summary> /// Remove from certificate store /// </summary> /// <param name="store"></param> /// <param name="certificates"></param> /// <returns></returns> public static void Remove(this ICertificateStore store, IEnumerable <X509Certificate2> certificates) { if (certificates == null) { throw new ArgumentNullException(nameof(certificates)); } foreach (var cert in certificates) { store.Delete(cert.Thumbprint); } }
private void MoveCertificate(DataRow row, Status status) { Status oldStatus = (Status)row[4]; row[4] = status; SetIcon(row, status); string targetStorePath = null; switch (status) { case Status.Trusted: { targetStorePath = m_trustedStorePath; break; } case Status.Issuer: { targetStorePath = m_issuerStorePath; break; } case Status.Rejected: { targetStorePath = m_rejectedStorePath; break; } } string oldStorePath = null; switch (oldStatus) { case Status.Trusted: { oldStorePath = m_trustedStorePath; break; } case Status.Issuer: { oldStorePath = m_issuerStorePath; break; } case Status.Rejected: { oldStorePath = m_rejectedStorePath; break; } } X509Certificate2 certificate = (X509Certificate2)row[7]; if (oldStorePath != targetStorePath) { if (!String.IsNullOrEmpty(targetStorePath)) { using (ICertificateStore store = CreateStore(targetStorePath)) { store.Add(certificate); } } if (!String.IsNullOrEmpty(oldStorePath)) { using (ICertificateStore store = CreateStore(oldStorePath)) { store.Delete(certificate.Thumbprint); } } } }
/// <summary> /// Add to certificate store /// </summary> /// <param name="store"></param> /// <param name="certificates"></param> /// <param name="noCopy"></param> /// <returns></returns> public static void Add(this ICertificateStore store, IEnumerable <X509Certificate2> certificates, bool noCopy = false) { if (certificates == null) { throw new ArgumentNullException(nameof(certificates)); } foreach (var cert in certificates) { Try.Op(() => store.Delete(cert.Thumbprint)); store.Add(noCopy ? cert : new X509Certificate2(cert)); } }
private async void DeleteMI_Click(object sender, EventArgs e) { try { if (ItemsLV.SelectedItems.Count < 1) { return; } DialogResult result = MessageBox.Show( "Are you sure you wish to delete the certificates from the store?", "Delete Certificate", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); if (result != DialogResult.Yes) { return; } // remove the certificates. List <ListViewItem> itemsToDelete = new List <ListViewItem>(); ICertificateStore store = m_storeId.OpenStore(); for (int ii = 0; ii < ItemsLV.SelectedItems.Count; ii++) { X509Certificate2 certificate = ItemsLV.SelectedItems[ii].Tag as X509Certificate2; if (certificate != null) { await store.Delete(certificate.Thumbprint); itemsToDelete.Add(ItemsLV.SelectedItems[ii]); } } // remove the items. foreach (ListViewItem itemToDelete in itemsToDelete) { itemToDelete.Remove(); } } catch (Exception exception) { GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception); Initialize(m_storeId, m_thumbprints); } }
/// <summary> /// Saves the certificate in the invalid certificate directory. /// </summary> private void SaveCertificate(X509Certificate2 certificate) { try { ICertificateStore store = m_rejectedCertificateStore.OpenStore(); try { store.Delete(certificate.Thumbprint); store.Add(certificate); } finally { store.Close(); } } catch (Exception e) { Utils.Trace(e, "Could not write certificate to directory: {0}", m_rejectedCertificateStore); } }
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> /// Deletes an existing application instance certificate. /// </summary> /// <param name="configuration">The configuration instance that stores the configurable information for a UA application.</param> private static async Task DeleteApplicationInstanceCertificate(ApplicationConfiguration configuration) { Utils.Trace(Utils.TraceMasks.Information, "Deleting application instance certificate."); // create a default certificate id none specified. CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate; if (id == null) { return; } // delete private key. X509Certificate2 certificate = await id.Find().ConfigureAwait(false); // delete trusted peer certificate. if (configuration.SecurityConfiguration != null && configuration.SecurityConfiguration.TrustedPeerCertificates != null) { string thumbprint = id.Thumbprint; if (certificate != null) { thumbprint = certificate.Thumbprint; } if (!string.IsNullOrEmpty(thumbprint)) { using (ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore()) { await store.Delete(thumbprint).ConfigureAwait(false); } } } // delete private key. if (certificate != null) { using (ICertificateStore store = id.OpenStore()) { await store.Delete(certificate.Thumbprint).ConfigureAwait(false); } } }
/// <summary> /// Adds the certificate to the Trusted Certificate Store /// </summary> /// <param name="configuration">The application's configuration which specifies the location of the TrustedStore.</param> /// <param name="certificate">The certificate to register.</param> public static async Task AddToTrustedStore(ApplicationConfiguration configuration, X509Certificate2 certificate) { ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore(); try { // check if it already exists. X509Certificate2Collection existingCertificates = await store.FindByThumbprint(certificate.Thumbprint); if (existingCertificates.Count > 0) { return; } List <string> subjectName = Utils.ParseDistinguishedName(certificate.Subject); // check for old certificate. X509Certificate2Collection certificates = await store.Enumerate(); for (int ii = 0; ii < certificates.Count; ii++) { if (Utils.CompareDistinguishedName(certificates[ii], subjectName)) { if (certificates[ii].Thumbprint == certificate.Thumbprint) { return; } await store.Delete(certificates[ii].Thumbprint); break; } } // add new certificate. X509Certificate2 publicKey = new X509Certificate2(certificate.RawData); await store.Add(publicKey); } finally { store.Close(); } }
/// <summary> /// Deletes an existing application instance certificate. /// </summary> /// <param name="configuration">The configuration instance that stores the configurable information for a UA application.</param> public static void DeleteApplicationInstanceCertificate(ApplicationConfiguration configuration) { // create a default certificate id none specified. CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate; if (id == null) { return; } // delete private key. X509Certificate2 certificate = id.Find(); // delete trusted peer certificate. if (configuration.SecurityConfiguration != null && configuration.SecurityConfiguration.TrustedPeerCertificates != null) { string thumbprint = id.Thumbprint; if (certificate != null) { thumbprint = certificate.Thumbprint; } if (!String.IsNullOrEmpty(thumbprint)) { using (ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore()) { store.Delete(thumbprint); } } } // delete private key. if (certificate != null) { using (ICertificateStore store = id.OpenStore()) { store.Delete(certificate.Thumbprint); } } }
/// <summary> /// Deletes an existing application instance certificate. /// </summary> /// <param name="configuration">The configuration instance that stores the configurable information for a UA application.</param> private static void DeleteApplicationInstanceCertificate(ApplicationConfiguration configuration) { Utils.Trace(Utils.TraceMasks.Information, "Deleting application instance certificate."); // Create a default certificate id none specified. CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate; if (id == null) { return; } X509Certificate2 certificate = id.Find(); // Delete trusted peer certificate. if (configuration.SecurityConfiguration?.TrustedPeerCertificates != null) { var thumbprint = id.Thumbprint; if (certificate != null) { thumbprint = certificate.Thumbprint; } using (var store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore()) { store.Delete(thumbprint); } } // Delete private key. if (certificate == null) { return; } using (ICertificateStore store = id.OpenStore()) { store.Delete(certificate.Thumbprint); } }
private async Task <bool> UpdateStoreCertificates( CertificateTrustList trustList, X509Certificate2Collection updatedCerts) { bool result = true; ICertificateStore store = null; try { store = trustList.OpenStore(); var storeCerts = await store.Enumerate().ConfigureAwait(false); foreach (var cert in storeCerts) { if (!updatedCerts.Contains(cert)) { if (!store.Delete(cert.Thumbprint).Result) { result = false; } } else { updatedCerts.Remove(cert); } } foreach (var cert in updatedCerts) { await store.Add(cert).ConfigureAwait(false); } } catch { result = false; } finally { store?.Close(); } return(result); }
private async Task <bool> UpdateStoreCertificates( string storePath, X509Certificate2Collection updatedCerts) { bool result = true; try { using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(storePath)) { var storeCerts = await store.Enumerate().ConfigureAwait(false); foreach (var cert in storeCerts) { if (!updatedCerts.Contains(cert)) { if (!await store.Delete(cert.Thumbprint).ConfigureAwait(false)) { result = false; } } else { updatedCerts.Remove(cert); } } foreach (var cert in updatedCerts) { await store.Add(cert).ConfigureAwait(false); } } } catch { result = false; } return(result); }
private bool UpdateStoreCertificates( string storePath, X509Certificate2Collection updatedCerts) { bool result = true; try { using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(storePath)) { var storeCerts = store.Enumerate().Result; foreach (var cert in storeCerts) { if (!updatedCerts.Contains(cert)) { if (!store.Delete(cert.Thumbprint).Result) { result = false; } } else { updatedCerts.Remove(cert); } } foreach (var cert in updatedCerts) { store.Add(cert).Wait(); } } } catch { result = false; } return(result); }
private ServiceResult ApplyChanges( ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments) { HasApplicationSecureAdminAccess(context); bool disconnectSessions = false; foreach (var certificateGroup in m_certificateGroups) { try { var updateCertificate = certificateGroup.UpdateCertificate; if (updateCertificate != null) { if (certificateGroup.UpdateCertificate.SessionId == context.SessionId) { using (ICertificateStore appStore = CertificateStoreIdentifier.OpenStore(certificateGroup.ApplicationCertificate.StorePath)) { appStore.Delete(certificateGroup.ApplicationCertificate.Thumbprint).Wait(); appStore.Add(updateCertificate.CertificateWithPrivateKey).Wait(); updateCertificate.CertificateWithPrivateKey = null; } using (ICertificateStore issuerStore = CertificateStoreIdentifier.OpenStore(certificateGroup.IssuerStorePath)) { foreach (var issuer in updateCertificate.IssuerCollection) { try { issuerStore.Add(issuer).Wait(); } catch (ArgumentException) { // ignore error if issuer cert already exists } } } disconnectSessions = true; } } } finally { certificateGroup.UpdateCertificate = null; } } if (disconnectSessions) { Task.Run(async() => { // give the client some time to receive the response // before the certificate update may disconnect all sessions await Task.Delay(1000).ConfigureAwait(false); await m_configuration.CertificateValidator.UpdateCertificate(m_configuration.SecurityConfiguration); } ); } return(StatusCodes.Good); }
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); }
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> /// Adds the certificate to the Trusted Certificate Store /// </summary> /// <param name="configuration">The application's configuration which specifies the location of the TrustedStore.</param> /// <param name="certificate">The certificate to register.</param> private static async Task AddToTrustedStore(ApplicationConfiguration configuration, X509Certificate2 certificate) { if (certificate == null) { throw new ArgumentNullException(nameof(certificate)); } string storePath = null; if (configuration != null && configuration.SecurityConfiguration != null && configuration.SecurityConfiguration.TrustedPeerCertificates != null) { storePath = configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath; } if (String.IsNullOrEmpty(storePath)) { Utils.Trace(Utils.TraceMasks.Information, "WARNING: Trusted peer store not specified."); return; } try { ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore(); if (store == null) { Utils.Trace("Could not open trusted peer store. StorePath={0}", storePath); return; } try { // check if it already exists. X509Certificate2Collection existingCertificates = await store.FindByThumbprint(certificate.Thumbprint); if (existingCertificates.Count > 0) { return; } Utils.Trace(Utils.TraceMasks.Information, "Adding certificate to trusted peer store. StorePath={0}", storePath); List <string> subjectName = X509Utils.ParseDistinguishedName(certificate.Subject); // check for old certificate. X509Certificate2Collection certificates = await store.Enumerate(); for (int ii = 0; ii < certificates.Count; ii++) { if (X509Utils.CompareDistinguishedName(certificates[ii], subjectName)) { if (certificates[ii].Thumbprint == certificate.Thumbprint) { return; } await store.Delete(certificates[ii].Thumbprint); break; } } // add new certificate. X509Certificate2 publicKey = new X509Certificate2(certificate.RawData); await store.Add(publicKey); } finally { store.Close(); } } catch (Exception e) { Utils.Trace(e, "Could not add certificate to trusted peer store. StorePath={0}", storePath); } }
private ServiceResult UpdateCertificate( ISystemContext context, MethodState method, NodeId objectId, NodeId certificateGroupId, NodeId certificateTypeId, byte[] certificate, byte[][] issuerCertificates, string privateKeyFormat, byte[] privateKey, ref bool applyChangesRequired) { HasApplicationSecureAdminAccess(context); if (certificate == null) { throw new ArgumentNullException(nameof(certificate)); } privateKeyFormat = privateKeyFormat?.ToUpper(); if (!(String.IsNullOrEmpty(privateKeyFormat) || privateKeyFormat == "PEM" || privateKeyFormat == "PFX")) { throw new ServiceResultException(StatusCodes.BadNotSupported, "The private key format is not supported."); } ServerCertificateGroup certificateGroup = VerifyGroupAndTypeId(certificateGroupId, certificateTypeId); certificateGroup.UpdateCertificate = null; X509Certificate2Collection newIssuerCollection = new X509Certificate2Collection(); X509Certificate2 newCert; try { // build issuer chain if (issuerCertificates != null) { foreach (byte[] issuerRawCert in issuerCertificates) { var newIssuerCert = new X509Certificate2(issuerRawCert); newIssuerCollection.Add(newIssuerCert); } } newCert = new X509Certificate2(certificate); } catch { throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Certificate data is invalid."); } // validate new subject matches the previous subject if (!X509Utils.CompareDistinguishedName(certificateGroup.ApplicationCertificate.SubjectName, newCert.SubjectName.Name)) { throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Subject Name of new certificate doesn't match the application."); } // self signed bool selfSigned = X509Utils.CompareDistinguishedName(newCert.Subject, newCert.Issuer); if (selfSigned && newIssuerCollection.Count != 0) { throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Issuer list not empty for self signed certificate."); } if (!selfSigned) { try { // verify cert with issuer chain CertificateValidator certValidator = new CertificateValidator(); CertificateTrustList issuerStore = new CertificateTrustList(); CertificateIdentifierCollection issuerCollection = new CertificateIdentifierCollection(); foreach (var issuerCert in newIssuerCollection) { issuerCollection.Add(new CertificateIdentifier(issuerCert)); } issuerStore.TrustedCertificates = issuerCollection; certValidator.Update(issuerStore, issuerStore, null); certValidator.Validate(newCert); } catch { throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Failed to verify integrity of the new certificate and the issuer list."); } } var updateCertificate = new UpdateCertificateData(); try { var passwordProvider = m_configuration.SecurityConfiguration.CertificatePasswordProvider; switch (privateKeyFormat) { case null: case "": { X509Certificate2 certWithPrivateKey = certificateGroup.ApplicationCertificate.LoadPrivateKeyEx(passwordProvider).Result; updateCertificate.CertificateWithPrivateKey = CertificateFactory.CreateCertificateWithPrivateKey(newCert, certWithPrivateKey); break; } case "PFX": { X509Certificate2 certWithPrivateKey = X509Utils.CreateCertificateFromPKCS12(privateKey, passwordProvider?.GetPassword(certificateGroup.ApplicationCertificate)); updateCertificate.CertificateWithPrivateKey = CertificateFactory.CreateCertificateWithPrivateKey(newCert, certWithPrivateKey); break; } case "PEM": { updateCertificate.CertificateWithPrivateKey = CertificateFactory.CreateCertificateWithPEMPrivateKey(newCert, privateKey, passwordProvider?.GetPassword(certificateGroup.ApplicationCertificate)); break; } } updateCertificate.IssuerCollection = newIssuerCollection; updateCertificate.SessionId = context.SessionId; } catch { throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Failed to verify integrity of the new certificate and the private key."); } certificateGroup.UpdateCertificate = updateCertificate; applyChangesRequired = true; if (updateCertificate != null) { try { using (ICertificateStore appStore = certificateGroup.ApplicationCertificate.OpenStore()) { Utils.LogCertificate(Utils.TraceMasks.Security, "Delete application certificate: ", certificateGroup.ApplicationCertificate.Certificate); appStore.Delete(certificateGroup.ApplicationCertificate.Thumbprint).Wait(); Utils.LogCertificate(Utils.TraceMasks.Security, "Add new application certificate: ", updateCertificate.CertificateWithPrivateKey); var passwordProvider = m_configuration.SecurityConfiguration.CertificatePasswordProvider; appStore.Add(updateCertificate.CertificateWithPrivateKey, passwordProvider?.GetPassword(certificateGroup.ApplicationCertificate)).Wait(); // keep only track of cert without private key var certOnly = new X509Certificate2(updateCertificate.CertificateWithPrivateKey.RawData); updateCertificate.CertificateWithPrivateKey.Dispose(); updateCertificate.CertificateWithPrivateKey = certOnly; } using (ICertificateStore issuerStore = CertificateStoreIdentifier.OpenStore(certificateGroup.IssuerStorePath)) { foreach (var issuer in updateCertificate.IssuerCollection) { try { Utils.LogCertificate(Utils.TraceMasks.Security, "Add new issuer certificate: ", issuer); issuerStore.Add(issuer).Wait(); } catch (ArgumentException) { // ignore error if issuer cert already exists } } } } catch (Exception ex) { Utils.LogError(Utils.TraceMasks.Security, ServiceResult.BuildExceptionTrace(ex)); throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Failed to update certificate.", ex); } } return(ServiceResult.Good); }
/// <summary> /// Adds the certificate to the Trusted Certificate Store /// </summary> /// <param name="configuration">The application's configuration which specifies the location of the TrustedStore.</param> /// <param name="certificate">The certificate to register.</param> private static void AddToTrustedStore(ApplicationConfiguration configuration, X509Certificate2 certificate) { var storePath = configuration?.SecurityConfiguration?.TrustedPeerCertificates?.StorePath; if (string.IsNullOrEmpty(storePath)) { Utils.Trace(Utils.TraceMasks.Information, "WARNING: Trusted peer store not specified."); return; } try { ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore(); if (store == null) { Utils.Trace("Could not open trusted peer store. StorePath={0}", storePath); return; } try { // check if it is already stored X509Certificate2 certificate2 = store.FindByThumbprint(certificate.Thumbprint); if (certificate2 != null) { return; } Utils.Trace(Utils.TraceMasks.Information, "Adding certificate to trusted peer store. StorePath={0}", storePath); List <string> subjectName = Utils.ParseDistinguishedName(certificate.Subject); // check for old certificate. X509Certificate2Collection certificates = store.Enumerate(); foreach (var cert in certificates) { if (!Utils.CompareDistinguishedName(cert, subjectName)) { continue; } if (cert.Thumbprint == certificate.Thumbprint) { return; } store.Delete(cert.Thumbprint); break; } // add new certificate. X509Certificate2 publicKey = new X509Certificate2(certificate.GetRawCertData()); store.Add(publicKey); } finally { store.Close(); } } catch (Exception e) { Utils.Trace(e, "Could not add certificate to trusted peer store. StorePath={0}", storePath); } }
/// <summary> /// Uninstalls a UA application. /// </summary> public static async Task UninstallApplication(InstalledApplication application) { // validate the executable file. string executableFile = Utils.GetAbsoluteFilePath(application.ExecutableFile, true, true, false); // get the default application name from the executable file. FileInfo executableFileInfo = new FileInfo(executableFile); string applicationName = executableFileInfo.Name.Substring(0, executableFileInfo.Name.Length - 4); // choose a default configuration file. if (String.IsNullOrEmpty(application.ConfigurationFile)) { application.ConfigurationFile = Utils.Format( "{0}\\{1}.Config.xml", executableFileInfo.DirectoryName, applicationName); } // validate the configuration file. string configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, false, false); if (configurationFile != null) { // load the current configuration. Opc.Ua.Security.SecuredApplication security = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configurationFile); // delete the application certificates. if (application.DeleteCertificatesOnUninstall) { CertificateIdentifier id = Opc.Ua.Security.SecuredApplication.FromCertificateIdentifier(security.ApplicationCertificate); // delete public key from trusted peers certificate store. try { CertificateStoreIdentifier certificateStore = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(security.TrustedCertificateStore); using (ICertificateStore store = certificateStore.OpenStore()) { X509Certificate2Collection peerCertificates = await store.FindByThumbprint(id.Thumbprint); if (peerCertificates.Count > 0) { await store.Delete(peerCertificates[0].Thumbprint); } } } catch (Exception e) { Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message); } // delete private key from application certificate store. try { using (ICertificateStore store = id.OpenStore()) { await store.Delete(id.Thumbprint); } } catch (Exception e) { Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message); } // permentently delete any UA defined stores if they are now empty. try { WindowsCertificateStore store = new WindowsCertificateStore(); await store.Open("LocalMachine\\UA Applications"); X509Certificate2Collection collection = await store.Enumerate(); if (collection.Count == 0) { store.PermanentlyDeleteStore(); } } catch (Exception e) { Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message); } } // remove the permissions for the HTTP endpoints used by the application. if (application.BaseAddresses != null && application.BaseAddresses.Count > 0) { List <ApplicationAccessRule> noRules = new List <ApplicationAccessRule>(); for (int ii = 0; ii < application.BaseAddresses.Count; ii++) { Uri url = Utils.ParseUri(application.BaseAddresses[ii]); if (url != null) { try { HttpAccessRule.SetAccessRules(url, noRules, true); Utils.Trace("Removed HTTP access rules for URL: {0}", url); } catch (Exception e) { Utils.Trace("Could not remove HTTP access rules for URL: {0}. Error={1}", url, e.Message); } } } } } }
private async void DeleteMI_Click(object sender, EventArgs e) { try { if (ItemsLV.SelectedItems.Count < 1) { return; } DialogResult result = MessageBox.Show( "Are you sure you wish to delete the certificates from the store?", "Delete Certificate", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); if (result != DialogResult.Yes) { return; } // remove the certificates. List <ListViewItem> itemsToDelete = new List <ListViewItem>(); bool yesToAll = false; using (ICertificateStore store = m_storeId.OpenStore()) { for (int ii = 0; ii < ItemsLV.SelectedItems.Count; ii++) { X509Certificate2 certificate = ItemsLV.SelectedItems[ii].Tag as X509Certificate2; // check for private key. X509Certificate2Collection certificate2 = await store.FindByThumbprint(certificate.Thumbprint); if (!yesToAll && (certificate2.Count > 0) && certificate2[0].HasPrivateKey) { StringBuilder buffer = new StringBuilder(); buffer.Append("Certificate '"); buffer.Append(certificate2[0].Subject); buffer.Append("'"); buffer.Append("Deleting it may cause applications to stop working."); buffer.Append("\r\n"); buffer.Append("\r\n"); buffer.Append("Are you sure you wish to continue?."); DialogResult yesno = new YesNoDlg().ShowDialog(buffer.ToString(), "Delete Private Key", true); if (yesno == DialogResult.No) { continue; } yesToAll = yesno == DialogResult.Retry; } if (certificate != null) { await store.Delete(certificate.Thumbprint); itemsToDelete.Add(ItemsLV.SelectedItems[ii]); } } } // remove the items. foreach (ListViewItem itemToDelete in itemsToDelete) { itemToDelete.Remove(); } } catch (Exception exception) { GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception); await Initialize(m_storeId, m_thumbprints); } }
private void OkBTN_Click(object sender, EventArgs e) { try { IPAddress address = IPAddress.Parse(IPAddressTB.Text); ushort port = (ushort)PortUD.Value; if (m_certificate == null) { throw new ArgumentException("You must specify a certificate."); } X509Certificate2 certificate = m_certificate.Find(true); if (certificate == null) { throw new ArgumentException("Certificate does not exist or has no private key."); } // setup policy chain X509ChainPolicy policy = new X509ChainPolicy(); policy.RevocationFlag = X509RevocationFlag.EntireChain; policy.RevocationMode = X509RevocationMode.Offline; policy.VerificationFlags = X509VerificationFlags.NoFlag; policy.VerificationFlags |= X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreCtlSignerRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreRootRevocationUnknown; // build chain. X509Chain chain = new X509Chain(); chain.ChainPolicy = policy; chain.Build(certificate); for (int ii = 0; ii < chain.ChainElements.Count; ii++) { X509ChainElement element = chain.ChainElements[ii]; // check for chain status errors. foreach (X509ChainStatus status in element.ChainElementStatus) { if (status.Status == X509ChainStatusFlags.UntrustedRoot) { if (!Ask("Cannot verify certificate up to a trusted root.\r\nAdd anyways?")) { return; } continue; } if (status.Status == X509ChainStatusFlags.RevocationStatusUnknown) { if (!Ask("The revocation status of this certificate cannot be verified.\r\nAdd anyways?")) { return; } continue; } // ignore informational messages. if (status.Status == X509ChainStatusFlags.OfflineRevocation) { continue; } if (status.Status != X509ChainStatusFlags.NoError) { throw new ArgumentException("[" + status.Status + "] " + status.StatusInformation); } } } // get the target store. if (m_store == null) { m_store = new CertificateStoreIdentifier(); m_store.StoreType = CertificateStoreType.Windows; m_store.StorePath = CertificateStoreTB.Text; } if (m_store.StoreType != CertificateStoreType.Windows) { throw new ArgumentException("You must choose a Windows store for SSL certificates."); } if (!m_store.StorePath.StartsWith("LocalMachine\\", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException("You must choose a machine store for SSL certificates."); } bool deleteExisting = false; using (ICertificateStore store = m_store.OpenStore()) { if (store.FindByThumbprint(certificate.Thumbprint) == null) { store.Add(certificate); deleteExisting = true; } } if (deleteExisting) { if (Ask("Would you like to delete the certificate from its current location?")) { using (ICertificateStore store = m_certificate.OpenStore()) { store.Delete(certificate.Thumbprint); } } } SslCertificateBinding binding = new SslCertificateBinding(); binding.IPAddress = address; binding.Port = port; binding.Thumbprint = certificate.Thumbprint; binding.ApplicationId = s_DefaultApplicationId; binding.StoreName = null; if (!m_store.StorePath.EndsWith("\\My")) { int index = m_store.StorePath.LastIndexOf("\\"); binding.StoreName = m_store.StorePath.Substring(index + 1); } HttpAccessRule.SetSslCertificateBinding(binding); m_binding = binding; DialogResult = DialogResult.OK; } catch (Exception exception) { GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception); } }
public async Task VerifyAppCertDirectoryStore() { var appCertificate = GetTestCert(); Assert.NotNull(appCertificate); Assert.True(appCertificate.HasPrivateKey); string password = Guid.NewGuid().ToString(); // pki directory root for app cert var pkiRoot = Path.GetTempPath() + Path.GetRandomFileName() + Path.DirectorySeparatorChar; var storePath = pkiRoot + "own"; var storeType = CertificateStoreType.Directory; appCertificate.AddToStore( storeType, storePath, password ); using (var publicKey = new X509Certificate2(appCertificate.RawData)) { Assert.NotNull(publicKey); Assert.False(publicKey.HasPrivateKey); var id = new CertificateIdentifier() { Thumbprint = publicKey.Thumbprint, StorePath = storePath, StoreType = storeType }; { // check no password fails to load var nullKey = await id.LoadPrivateKey(null).ConfigureAwait(false); Assert.IsNull(nullKey); } { // check invalid password fails to load var nullKey = await id.LoadPrivateKey("123").ConfigureAwait(false); Assert.IsNull(nullKey); } { // check invalid password fails to load var nullKey = await id.LoadPrivateKeyEx(new CertificatePasswordProvider("123")).ConfigureAwait(false); Assert.IsNull(nullKey); } var privateKey = await id.LoadPrivateKeyEx(new CertificatePasswordProvider(password)).ConfigureAwait(false); Assert.NotNull(privateKey); Assert.True(privateKey.HasPrivateKey); X509Utils.VerifyRSAKeyPair(publicKey, privateKey, true); using (ICertificateStore store = Opc.Ua.CertificateStoreIdentifier.CreateStore(storeType)) { store.Open(storePath); await store.Delete(publicKey.Thumbprint).ConfigureAwait(false); } } }