/// <summary>
        /// Displays the applications in the control.
        /// </summary>
        internal async void Initialize(CertificateStoreIdentifier id, IList <string> thumbprints)
        {
            ItemsLV.Items.Clear();

            m_storeId     = id;
            m_thumbprints = thumbprints;

            if (m_storeId == null || String.IsNullOrEmpty(m_storeId.StoreType) || String.IsNullOrEmpty(m_storeId.StorePath))
            {
                Instructions = "No certificates are in the store.";
                AdjustColumns();
                return;
            }

            try
            {
                // get the store.
                ICertificateStore store = m_storeId.OpenStore();

                // only show certificates with the specified thumbprint.
                if (thumbprints != null)
                {
                    Instructions = "None of the selected certificates can be found in the store.";

                    foreach (string thumbprint in thumbprints)
                    {
                        X509Certificate2Collection certificates = await store.FindByThumbprint(thumbprint);

                        if (certificates.Count > 0)
                        {
                            AddItem(certificates[0]);
                        }
                    }
                }

                // show all certificates.
                else
                {
                    Instructions = "No certificates are in the store.";

                    X509Certificate2Collection certificates = await store.Enumerate();

                    foreach (X509Certificate2 certificate in certificates)
                    {
                        AddItem(certificate);
                    }
                }
            }
            catch (Exception e)
            {
                Instructions = "An error occurred opening the store: " + e.Message;
            }

            // save the unfiltered list.
            m_items = new List <ListViewItem>(ItemsLV.Items.Count);

            foreach (ListViewItem item in ItemsLV.Items)
            {
                m_items.Add(item);
            }

            AdjustColumns();
        }
        /// <summary>
        /// Adds a certificate binding to to list.
        /// </summary>
        private void AddRow(SslCertificateBinding binding)
        {
            DataRow row = m_dataset.Tables[0].NewRow();

            row[0] = binding.IPAddress;
            row[1] = binding.Port;
            row[3] = binding.Thumbprint;
            row[4] = binding;

            CertificateStoreIdentifier id = new CertificateStoreIdentifier();
            id.StoreType = CertificateStoreType.Windows;
            id.StorePath = "LocalMachine\\" + ((String.IsNullOrEmpty(binding.StoreName)) ? "My" : binding.StoreName);

            using (ICertificateStore store = id.OpenStore())
            {
                X509Certificate2 certificate = store.FindByThumbprint(binding.Thumbprint);

                if (certificate != null)
                {
                    row[2] = certificate.Subject;
                }
                else
                {
                    row[2] = "<not found>";
                }
            }

            m_dataset.Tables[0].Rows.Add(row);
        }
        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.Certificate.SubjectName, newCert.SubjectName))
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Subject Name of new certificate doesn't match the application.");
            }

            // self signed
            bool selfSigned = X509Utils.IsSelfSigned(newCert);

            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);
        }
Beispiel #4
0
        /// <summary>
        /// Updates an item in the view.
        /// </summary>
        protected override void UpdateItem(ListViewItem listItem, object item)
        {
            X509Certificate2 certificate = item as X509Certificate2;

            if (certificate == null)
            {
                base.UpdateItem(listItem, item);
                return;
            }

            listItem.SubItems[0].Text = null;
            listItem.SubItems[1].Text = null;
            listItem.SubItems[2].Text = null;
            listItem.SubItems[3].Text = null;
            listItem.SubItems[4].Text = null;
            listItem.SubItems[5].Text = null;

            if (certificate != null)
            {
                List <string> fields = Utils.ParseDistinguishedName(certificate.Subject);

                for (int ii = 0; ii < fields.Count; ii++)
                {
                    if (fields[ii].StartsWith("CN="))
                    {
                        listItem.SubItems[0].Text = fields[ii].Substring(3);
                    }

                    if (fields[ii].StartsWith("DC="))
                    {
                        listItem.SubItems[1].Text = fields[ii].Substring(3);
                    }
                }

                if (String.IsNullOrEmpty(listItem.SubItems[0].Text))
                {
                    listItem.SubItems[0].Text = String.Format("{0}", certificate.Subject);
                }

                // determine certificate type.
                foreach (X509Extension extension in certificate.Extensions)
                {
                    X509BasicConstraintsExtension basicContraints = extension as X509BasicConstraintsExtension;

                    if (basicContraints != null)
                    {
                        if (basicContraints.CertificateAuthority)
                        {
                            listItem.SubItems[1].Text = "CA";
                        }
                        else
                        {
                            listItem.SubItems[1].Text = "End-Entity";
                        }

                        break;
                    }
                }

                // check if a private key is available.
                if (certificate.HasPrivateKey)
                {
                    listItem.SubItems[2].Text = "Yes";
                }
                else
                {
                    listItem.SubItems[2].Text = "No";

                    if (m_storeId != null)
                    {
                        ICertificateStore store = m_storeId.OpenStore();

                        try
                        {
                            if (store.GetPrivateKeyFilePath(certificate.Thumbprint) != null)
                            {
                                listItem.SubItems[2].Text = "Yes (No Access)";
                            }
                        }
                        catch (Exception e)
                        {
                            listItem.SubItems[2].Text = e.Message;
                        }
                        finally
                        {
                            store.Close();
                        }
                    }
                }

                // look up domains.
                IList <string> domains = Utils.GetDomainsFromCertficate(certificate);

                StringBuilder buffer = new StringBuilder();

                for (int ii = 0; ii < domains.Count; ii++)
                {
                    if (buffer.Length > 0)
                    {
                        buffer.Append(";");
                    }

                    buffer.Append(domains[ii]);
                }

                listItem.SubItems[3].Text = buffer.ToString();
                listItem.SubItems[4].Text = Utils.GetApplicationUriFromCertficate(certificate);
                listItem.SubItems[5].Text = String.Format("{0:yyyy-MM-dd}", certificate.NotAfter);
            }

            listItem.ImageKey = GuiUtils.Icons.Certificate;
            listItem.Tag      = item;
        }
        /// <summary>
        /// Displays the applications in the control.
        /// </summary>
        internal void Initialize(CertificateStoreIdentifier id, IList<string> thumbprints)
        {
            ItemsLV.Items.Clear();

            m_storeId = id;
            m_thumbprints = thumbprints;

            if (m_storeId == null || String.IsNullOrEmpty(m_storeId.StoreType) || String.IsNullOrEmpty(m_storeId.StorePath))
            {
                Instructions = "No certificates are in the store.";
                AdjustColumns();
                return;
            }

            try
            {
                // get the store.
                using (ICertificateStore store = m_storeId.OpenStore())
                {
                    // only show certificates with the specified thumbprint.
                    if (thumbprints != null)
                    {
                        Instructions = "None of the selected certificates can be found in the store.";

                        foreach (string thumbprint in thumbprints)
                        {
                            X509Certificate2 certificate = store.FindByThumbprint(thumbprint);

                            if (certificate != null)
                            {
                                AddItem(certificate);
                            }
                        }
                    }

                    // show all certificates.
                    else
                    {
                        Instructions = "No certificates are in the store.";

                        foreach (X509Certificate2 certificate in store.Enumerate())
                        {
                            AddItem(certificate);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Instructions = "An error occurred opening the store: " + e.Message;
            }
            
            // save the unfiltered list.
            m_items = new List<ListViewItem>(ItemsLV.Items.Count);

            foreach (ListViewItem item in ItemsLV.Items)
            {
                m_items.Add(item);
            }

            AdjustColumns();

        }
    /// <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);
    }
Beispiel #7
0
        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);
                    await m_configuration.CertificateValidator.UpdateCertificate(m_configuration.SecurityConfiguration);
                }
                         );
            }

            return(StatusCodes.Good);
        }
Beispiel #8
0
        private void ImportCertificateListToStoreBTN_Click(object sender, EventArgs e)
        {
            try
            {
                const string caption = "Import Certificate List";
                
                CertificateStoreIdentifier list1 = new CertificateStoreIdentifier();
                list1.StoreType = ManagedStoreCTRL.StoreType;
                list1.StorePath = ManagedStoreCTRL.StorePath;

                if (m_currentStore == null)
                {
                    m_currentStore = new CertificateStoreIdentifier();
                    m_currentStore.StoreType = Utils.DefaultStoreType;
                    m_currentStore.StorePath = Utils.DefaultStorePath;
                }

                CertificateStoreIdentifier list2 = new CertificateStoreDlg().ShowDialog(m_currentStore);

                if (list2 == null)
                {
                    return;
                }

                m_currentStore = list2;

                int count = 0;
                ICertificateStore store1 = list1.OpenStore();
                ICertificateStore store2 = list2.OpenStore();

                try
                {
                    foreach (X509Certificate2 certificate in store2.Enumerate())
                    {
                        if (store1.FindByThumbprint(certificate.Thumbprint) == null)
                        {
                            store1.Add(certificate);
                            count++;
                        }
                    }
                }
                finally
                {
                    store1.Close();
                    store2.Close();
                }

                MessageBox.Show(
                    this,
                    count.ToString() + " certificates added.",
                    caption,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
        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);
        }
Beispiel #10
0
        private async void CertificateRequestTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                NodeId requestId = NodeId.Parse(m_application.CertificateRequestId);

                byte[]   privateKey         = null;
                byte[][] issuerCertificates = null;

                byte[] certificate = m_gds.FinishRequest(
                    m_application.ApplicationId,
                    requestId,
                    out privateKey,
                    out issuerCertificates);

                if (certificate == null)
                {
                    return;
                }

                CertificateRequestTimer.Enabled = false;
                RequestProgressLabel.Visible    = false;

                if (m_application.RegistrationType != RegistrationType.ServerPush)
                {
                    // save public key.
                    if (!String.IsNullOrEmpty(m_application.CertificatePublicKeyPath))
                    {
                        string file = Utils.GetAbsoluteFilePath(m_application.CertificatePublicKeyPath, true, false, true);
                        File.WriteAllBytes(file, certificate);
                    }

                    // check if the private was re-used.
                    if (privateKey == null || privateKey.Length == 0)
                    {
                        if (!String.IsNullOrEmpty(m_application.CertificatePrivateKeyPath))
                        {
                            string path = Utils.GetAbsoluteFilePath(m_application.CertificatePrivateKeyPath, true, true, true);

                            if (path != null)
                            {
                                if (!m_application.CertificatePrivateKeyPath.EndsWith("PEM", StringComparison.OrdinalIgnoreCase))
                                {
                                    var x509   = new X509Certificate2(certificate);
                                    var oldPfx = new X509Certificate2(path, (string)null, X509KeyStorageFlags.Exportable);
                                    var newPfx = CertificateAuthority.Replace(x509, oldPfx);
                                    var bytes  = newPfx.Export(X509ContentType.Pfx);
                                    File.WriteAllBytes(path, bytes);
                                }
                            }
                        }
                        else
                        {
                            if (!String.IsNullOrEmpty(m_application.CertificateStorePath) && !String.IsNullOrEmpty(m_application.CertificateSubjectName))
                            {
                                var x509 = new X509Certificate2(certificate);

                                var cid = new CertificateIdentifier()
                                {
                                    StorePath   = m_application.CertificateStorePath,
                                    SubjectName = m_application.CertificateSubjectName.Replace("localhost", System.Net.Dns.GetHostName())
                                };

                                var oldPfx = await cid.Find(true);

                                if (oldPfx != null)
                                {
                                    var newPfx = CertificateAuthority.Replace(x509, oldPfx);

                                    using (var store = CertificateStoreIdentifier.OpenStore(m_application.CertificateStorePath))
                                    {
                                        await store.Delete(oldPfx.Thumbprint);

                                        await store.Add(newPfx);
                                    }
                                }
                            }
                        }
                    }

                    // save private key.
                    else
                    {
                        if (!String.IsNullOrEmpty(m_application.CertificatePrivateKeyPath))
                        {
                            string path = Utils.GetAbsoluteFilePath(m_application.CertificatePrivateKeyPath, true, true, true);

                            if (path != null)
                            {
                                File.WriteAllBytes(path, privateKey);
                            }
                        }
                        else
                        {
                            if (!String.IsNullOrEmpty(m_application.CertificateStorePath) && !String.IsNullOrEmpty(m_application.CertificateSubjectName))
                            {
                                var cid = new CertificateIdentifier()
                                {
                                    StorePath   = m_application.CertificateStorePath,
                                    SubjectName = m_application.CertificateSubjectName
                                };

                                var oldCertificate = await cid.Find();

                                using (var store = CertificateStoreIdentifier.OpenStore(m_application.CertificateStorePath))
                                {
                                    if (oldCertificate != null)
                                    {
                                        await store.Delete(oldCertificate.Thumbprint);
                                    }

                                    var x509 = new X509Certificate2(privateKey, new System.Security.SecureString(), X509KeyStorageFlags.Exportable);
                                    x509 = CertificateFactory.Load(x509, true);
                                    await store.Add(x509);
                                }
                            }
                        }
                    }

                    // update trust list.
                    if (!String.IsNullOrEmpty(m_application.TrustListStorePath))
                    {
                        using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_application.TrustListStorePath))
                        {
                            foreach (var issuerCertificate in issuerCertificates)
                            {
                                var x509 = new X509Certificate2(issuerCertificate);

                                if (store.FindByThumbprint(x509.Thumbprint) == null)
                                {
                                    await store.Add(new X509Certificate2(issuerCertificate));
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (privateKey != null && privateKey.Length > 0)
                    {
                        var x509 = new X509Certificate2(privateKey, m_certificatePassword, X509KeyStorageFlags.Exportable);
                        privateKey = x509.Export(X509ContentType.Pfx);
                    }

                    bool applyChanges = m_server.UpdateCertificate(null, null, certificate, GetPrivateKeyFormat(), privateKey, issuerCertificates);

                    if (applyChanges)
                    {
                        MessageBox.Show(
                            Parent,
                            "The certificate was updated, however, the apply changes command must be sent before the server will use the new certificate.",
                            Parent.Text,
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);

                        ApplyChangesButton.Enabled = true;
                    }
                }

                m_certificate = new X509Certificate2(certificate);
                CertificateControl.ShowValue(null, "Application Certificate", new CertificateWrapper()
                {
                    Certificate = m_certificate
                }, true);
            }
            catch (Exception exception)
            {
                var sre = exception as ServiceResultException;

                if (sre != null && sre.StatusCode == StatusCodes.BadNothingToDo)
                {
                    return;
                }

                MessageBox.Show(Parent.Text + ": " + exception.Message);
                CertificateRequestTimer.Enabled = false;
            }
        }
Beispiel #11
0
        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);
            }
        }
Beispiel #12
0
        private void PullFromGds(bool deleteBeforeAdd)
        {
            try
            {
                NodeId trustListId = m_gds.GetTrustList(m_application.ApplicationId, null);

                if (trustListId == null)
                {
                    CertificateStoreControl.Initialize(null, null, null);
                    return;
                }

                var trustList = m_gds.ReadTrustList(trustListId);

                if (m_application.RegistrationType == RegistrationType.ServerPush)
                {
                    CertificateStoreControl.Initialize(trustList);

                    MessageBox.Show(
                        Parent,
                        "The trust list (include CRLs) was downloaded from the GDS. It now has to be pushed to the Server.",
                        Parent.Text,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);

                    return;
                }

                if (!String.IsNullOrEmpty(m_trustListStorePath))
                {
                    if (deleteBeforeAdd)
                    {
                        DeleteExistingFromStore(m_trustListStorePath).Wait();
                        DeleteExistingFromStore(m_issuerListStorePath).Wait();;
                    }
                }

                if (!String.IsNullOrEmpty(m_trustListStorePath))
                {
                    using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_trustListStorePath))
                    {
                        if ((trustList.SpecifiedLists & (uint)Opc.Ua.TrustListMasks.TrustedCertificates) != 0)
                        {
                            foreach (var certificate in trustList.TrustedCertificates)
                            {
                                var x509 = new X509Certificate2(certificate);

                                X509Certificate2Collection certs = store.FindByThumbprint(x509.Thumbprint).Result;
                                if (certs.Count == 0)
                                {
                                    store.Add(x509).Wait();
                                }
                            }
                        }

                        if ((trustList.SpecifiedLists & (uint)Opc.Ua.TrustListMasks.TrustedCrls) != 0)
                        {
                            foreach (var crl in trustList.TrustedCrls)
                            {
                                store.AddCRL(new X509CRL(crl));
                            }
                        }
                    }
                }

                if (!String.IsNullOrEmpty(m_application.IssuerListStorePath))
                {
                    using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_application.IssuerListStorePath))
                    {
                        if ((trustList.SpecifiedLists & (uint)Opc.Ua.TrustListMasks.IssuerCertificates) != 0)
                        {
                            foreach (var certificate in trustList.IssuerCertificates)
                            {
                                var x509 = new X509Certificate2(certificate);

                                X509Certificate2Collection certs = store.FindByThumbprint(x509.Thumbprint).Result;
                                if (certs.Count == 0)
                                {
                                    store.Add(x509).Wait();
                                }
                            }
                        }

                        if ((trustList.SpecifiedLists & (uint)Opc.Ua.TrustListMasks.IssuerCrls) != 0)
                        {
                            foreach (var crl in trustList.IssuerCrls)
                            {
                                store.AddCRL(new X509CRL(crl));
                            }
                        }
                    }
                }

                CertificateStoreControl.Initialize(m_trustListStorePath, m_issuerListStorePath, null);

                MessageBox.Show(
                    Parent,
                    "The trust list (include CRLs) was downloaded from the GDS and saved locally.",
                    Parent.Text,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
            catch (Exception exception)
            {
                MessageBox.Show(Parent.Text + ": " + exception.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);
            }
        }
        /// <summary>
        /// Adds an application certificate to a store.
        /// </summary>
        private static async Task AddApplicationCertificateToStore(
            CertificateStoreIdentifier csid,
            X509Certificate2 certificate,
            string oldThumbprint)
        {
            ICertificateStore store = csid.OpenStore();

            try
            {
                // delete the old certificate.
                if (oldThumbprint != null)
                {
                    await store.Delete(oldThumbprint);
                }

                // delete certificates with the same application uri.
                if (store.FindByThumbprint(certificate.Thumbprint) == null)
                {
                    string applicationUri = Utils.GetApplicationUriFromCertificate(certificate);

                    // delete any existing certificates.
                    X509Certificate2Collection collection = await store.Enumerate();
                    foreach (X509Certificate2 target in collection)
                    {
                        if (Utils.CompareDistinguishedName(target.Subject, certificate.Subject))
                        {
                            if (Utils.GetApplicationUriFromCertificate(target) == applicationUri)
                            {
                                await store.Delete(target.Thumbprint);
                            }
                        }
                    }

                    // add new certificate.
                    await store.Add(new X509Certificate2(certificate.RawData));
                }
            }
            finally
            {
                store.Close();
            }
        }
Beispiel #15
0
        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 (Utils.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 an application certificate to a store.
        /// </summary>
        private static void AddIssuerCertificatesToStore(CertificateStoreIdentifier csid, IList<X509Certificate2> issuers)
        {
            ICertificateStore store = csid.OpenStore();

            try
            {
                foreach (X509Certificate2 issuer in issuers)
                {
                    if (store.FindByThumbprint(issuer.Thumbprint) == null)
                    {
                        store.Add(issuer);
                    }
                }
            }
            finally
            {
                store.Close();
            }
        }
Beispiel #17
0
        private ServiceResult Open(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            OpenFileMode mode,
            TrustListMasks masks,
            ref uint fileHandle)
        {
            HasSecureReadAccess(context);

            if (mode == OpenFileMode.Read)
            {
                HasSecureReadAccess(context);
            }
            else if (mode == (OpenFileMode.Write | OpenFileMode.EraseExisting))
            {
                HasSecureWriteAccess(context);
            }
            else
            {
                return(StatusCodes.BadNotWritable);
            }

            lock (m_lock)
            {
                if (m_sessionId != null)
                {
                    // to avoid deadlocks, last open always wins
                    m_sessionId            = null;
                    m_strm                 = null;
                    m_node.OpenCount.Value = 0;
                }

                m_readMode  = mode == OpenFileMode.Read;
                m_sessionId = context.SessionId;
                fileHandle  = ++m_fileHandle;

                TrustListDataType trustList = new TrustListDataType()
                {
                    SpecifiedLists = (uint)masks
                };

                using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_trustedStorePath))
                {
                    if ((masks & TrustListMasks.TrustedCertificates) != 0)
                    {
                        X509Certificate2Collection certificates = store.Enumerate().Result;
                        foreach (var certificate in certificates)
                        {
                            trustList.TrustedCertificates.Add(certificate.RawData);
                        }
                    }

                    if ((masks & TrustListMasks.TrustedCrls) != 0)
                    {
                        foreach (var crl in store.EnumerateCRLs())
                        {
                            trustList.TrustedCrls.Add(crl.RawData);
                        }
                    }
                }

                using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_issuerStorePath))
                {
                    if ((masks & TrustListMasks.IssuerCertificates) != 0)
                    {
                        X509Certificate2Collection certificates = store.Enumerate().Result;
                        foreach (var certificate in certificates)
                        {
                            trustList.IssuerCertificates.Add(certificate.RawData);
                        }
                    }

                    if ((masks & TrustListMasks.IssuerCrls) != 0)
                    {
                        foreach (var crl in store.EnumerateCRLs())
                        {
                            trustList.IssuerCrls.Add(crl.RawData);
                        }
                    }
                }

                if (m_readMode)
                {
                    m_strm = EncodeTrustListData(context, trustList);
                }
                else
                {
                    m_strm = new MemoryStream(DefaultTrustListCapacity);
                }

                m_node.OpenCount.Value = 1;
            }

            return(ServiceResult.Good);
        }
Beispiel #18
0
        /// <summary>
        /// Validates a certificate and adds it to the trust list.
        /// </summary>
        private void ValidateAndImport(CertificateStoreIdentifier store, X509Certificate2 certificate)
        {
            if (store == null || certificate == null)
            {
                return;
            }

            // validate the certificate using the trust lists for the certificate tool.                                
            try
            {
                CertificateValidator validator = new CertificateValidator();
                validator.Update(m_configuration);
                validator.Validate(certificate);
            }
            catch (ServiceResultException exception)
            {
                if (!HandleValidationError(certificate, exception))
                {
                    return;
                }
            }

            // confirm import.
            StringBuilder buffer = new StringBuilder();

            buffer.Append("You are adding this certificate to a trust list that may be shared with other applications.");
            buffer.Append("\r\n");
            buffer.Append("\r\n");
            buffer.Append("Would you still like to accept the certificate?\r\n");
            buffer.Append("\r\n");
            buffer.Append("Target Trust List = ");
            buffer.Append(store.ToString());
            buffer.Append("\r\n");
            buffer.Append("Certificate to Add = ");
            buffer.Append(certificate.Subject);

            DialogResult result = new YesNoDlg().ShowDialog(buffer.ToString(), "Import Certificate to Trust List");

            if (result != DialogResult.Yes)
            {
                return;
            }

            // update store.
            ICertificateStore physicalStore = store.OpenStore();

            if (physicalStore.FindByThumbprint(certificate.Thumbprint) == null)
            {
                physicalStore.Add(new X509Certificate2(certificate.RawData));
            }
        }
    /// <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);

                var certificateCollection = new X509Certificate2Collection()
                {
                    certificate
                };
                updatedCRL = RevokeCertificate(certCAWithPrivateKey, certCACrl, certificateCollection);

                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);
    }
        private void OkBTN_Click(object sender, EventArgs e)
        {
            try
            {
                string storeType = null;
                string storePath = null;
                string domainName = null;
                string organization = null;
                string subjectName = SubjectNameTB.Text.Trim();
                string issuerKeyFilePath = IssuerKeyFilePathTB.Text.Trim();
                string issuerKeyFilePassword = IssuerPasswordTB.Text.Trim();

                if (String.IsNullOrEmpty(issuerKeyFilePath))
                {
                    throw new ApplicationException("Must provide an issuer certificate.");
                }

                // verify certificate.
                X509Certificate2 issuer = new X509Certificate2(
                    issuerKeyFilePath,
                    issuerKeyFilePassword,
                    X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
                
                if (!issuer.HasPrivateKey)
                {
                    throw new ApplicationException("Issuer certificate does not have a private key.");
                }

                // determine certificate type.
                foreach (X509Extension extension in issuer.Extensions)
                {
                    X509BasicConstraintsExtension basicContraints = extension as X509BasicConstraintsExtension;

                    if (basicContraints != null)
                    {
                        if (!basicContraints.CertificateAuthority)
                        {
                            throw new ApplicationException("Certificate cannot be used to issue new certificates.");
                        }
                    }
                }

                // check traget store.
                if (!String.IsNullOrEmpty(CertificateStoreCTRL.StorePath))
                {
                    storeType = CertificateStoreCTRL.StoreType;
                    storePath = CertificateStoreCTRL.StorePath;
                }

                if (String.IsNullOrEmpty(storePath))
                {
                    throw new ApplicationException("Please specify a store path.");
                }

                domainName = DomainNameTB.Text;
                organization = OrganizationTB.Text;

                // extract key fields from the subject name.
                if (SubjectNameCK.Checked)
                {
                    List<string> parts = Utils.ParseDistinguishedName(SubjectNameTB.Text);

                    for (int ii = 0; ii < parts.Count; ii++)
                    {
                        if (parts[ii].StartsWith("CN="))
                        {
                            domainName = parts[ii].Substring(3).Trim();
                        }

                        if (parts[ii].StartsWith("O="))
                        {
                            organization = parts[ii].Substring(2).Trim();
                        }
                    }
                }

                if (String.IsNullOrEmpty(domainName))
                {
                    throw new ApplicationException("Please specify a domain name.");
                }

                if (!String.IsNullOrEmpty(DomainNameTB.Text) && domainName != DomainNameTB.Text)
                {
                    throw new ApplicationException("The domain name must be the common name for the certificate.");
                }

                if (!String.IsNullOrEmpty(OrganizationTB.Text) && organization != OrganizationTB.Text)
                {
                    throw new ApplicationException("The organization must be the organization for the certificate.");
                }
                
                X509Certificate2 certificate = Opc.Ua.CertificateFactory.CreateCertificate(
                    storeType,
                    storePath,
                    null,
                    null,
                    domainName,
                    subjectName,
                    null,
                    Convert.ToUInt16(KeySizeCB.SelectedItem.ToString()),
                    DateTime.MinValue,
                    (ushort)LifeTimeInMonthsUD.Value,
                    0,
                    false,
                    false,
                    issuerKeyFilePath,
                    issuerKeyFilePassword);

                m_certificate = new CertificateIdentifier();
                m_certificate.StoreType = storeType;
                m_certificate.StorePath = storePath;
                m_certificate.Certificate = certificate;

                try
                {
                    CertificateStoreIdentifier rootStore = new CertificateStoreIdentifier();
                    rootStore.StoreType = CertificateStoreType.Windows;
                    rootStore.StorePath = "LocalMachine\\Root";

                    using (ICertificateStore store = rootStore.OpenStore())
                    {
                        X509Certificate2 rootCertificate = new X509Certificate2(issuerKeyFilePath, issuerKeyFilePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

                        if (store.FindByThumbprint(rootCertificate.Thumbprint) == null)
                        {
                            if (Ask("Would you like to install the signing certificate as a trusted root authority on this machine?"))
                            {
                                store.Add(new X509Certificate2(rootCertificate.RawData));
                            }
                        }
                    }
                }
                catch (Exception exception)
                {
                    GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
                }
                
                // close the dialog.
                DialogResult = DialogResult.OK;
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
            }
        }
        private void OkBTN_Click(object sender, EventArgs e)
        {
            try
            {
                string storeType             = null;
                string storePath             = null;
                string domainName            = null;
                string organization          = null;
                string subjectName           = SubjectNameTB.Text.Trim();
                string issuerKeyFilePath     = IssuerKeyFilePathTB.Text.Trim();
                string issuerKeyFilePassword = IssuerPasswordTB.Text.Trim();

                if (String.IsNullOrEmpty(issuerKeyFilePath))
                {
                    throw new ApplicationException("Must provide an issuer certificate.");
                }

                // verify certificate.
                X509Certificate2 issuer = new X509Certificate2(
                    issuerKeyFilePath,
                    issuerKeyFilePassword,
                    X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

                if (!issuer.HasPrivateKey)
                {
                    throw new ApplicationException("Issuer certificate does not have a private key.");
                }

                // determine certificate type.
                foreach (X509Extension extension in issuer.Extensions)
                {
                    X509BasicConstraintsExtension basicContraints = extension as X509BasicConstraintsExtension;

                    if (basicContraints != null)
                    {
                        if (!basicContraints.CertificateAuthority)
                        {
                            throw new ApplicationException("Certificate cannot be used to issue new certificates.");
                        }
                    }
                }

                // check traget store.
                if (!String.IsNullOrEmpty(CertificateStoreCTRL.StorePath))
                {
                    storeType = CertificateStoreCTRL.StoreType;
                    storePath = CertificateStoreCTRL.StorePath;
                }

                if (String.IsNullOrEmpty(storePath))
                {
                    throw new ApplicationException("Please specify a store path.");
                }

                domainName   = DomainNameTB.Text;
                organization = OrganizationTB.Text;

                // extract key fields from the subject name.
                if (SubjectNameCK.Checked)
                {
                    List <string> parts = Utils.ParseDistinguishedName(SubjectNameTB.Text);

                    for (int ii = 0; ii < parts.Count; ii++)
                    {
                        if (parts[ii].StartsWith("CN="))
                        {
                            domainName = parts[ii].Substring(3).Trim();
                        }

                        if (parts[ii].StartsWith("O="))
                        {
                            organization = parts[ii].Substring(2).Trim();
                        }
                    }
                }

                if (String.IsNullOrEmpty(domainName))
                {
                    throw new ApplicationException("Please specify a domain name.");
                }

                if (!String.IsNullOrEmpty(DomainNameTB.Text) && domainName != DomainNameTB.Text)
                {
                    throw new ApplicationException("The domain name must be the common name for the certificate.");
                }

                if (!String.IsNullOrEmpty(OrganizationTB.Text) && organization != OrganizationTB.Text)
                {
                    throw new ApplicationException("The organization must be the organization for the certificate.");
                }

                X509Certificate2 certificate = Opc.Ua.CertificateFactory.CreateCertificate(
                    storeType,
                    storePath,
                    null,
                    null,
                    domainName,
                    subjectName,
                    null,
                    Convert.ToUInt16(KeySizeCB.SelectedItem.ToString()),
                    DateTime.MinValue,
                    (ushort)LifeTimeInMonthsUD.Value,
                    0,
                    false,
                    false,
                    issuerKeyFilePath,
                    issuerKeyFilePassword);

                m_certificate             = new CertificateIdentifier();
                m_certificate.StoreType   = storeType;
                m_certificate.StorePath   = storePath;
                m_certificate.Certificate = certificate;

                try
                {
                    CertificateStoreIdentifier rootStore = new CertificateStoreIdentifier();
                    rootStore.StoreType = CertificateStoreType.Windows;
                    rootStore.StorePath = "LocalMachine\\Root";

                    using (ICertificateStore store = rootStore.OpenStore())
                    {
                        X509Certificate2 rootCertificate = new X509Certificate2(issuerKeyFilePath, issuerKeyFilePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

                        if (store.FindByThumbprint(rootCertificate.Thumbprint) == null)
                        {
                            if (Ask("Would you like to install the signing certificate as a trusted root authority on this machine?"))
                            {
                                store.Add(new X509Certificate2(rootCertificate.RawData));
                            }
                        }
                    }
                }
                catch (Exception exception)
                {
                    GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
                }

                // close the dialog.
                DialogResult = DialogResult.OK;
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
            }
        }