Beispiel #1
0
 private void CheckPEMWriter(X509Certificate2 certificate, string password = null)
 {
     PEMWriter.ExportCertificateAsPEM(certificate);
     if (certificate.HasPrivateKey)
     {
         PEMWriter.ExportPrivateKeyAsPEM(certificate, password);
         PEMWriter.ExportECDsaPrivateKeyAsPEM(certificate);
     }
 }
Beispiel #2
0
        public void VerifyPemWriterPublicKeys()
        {
            // all app certs are trusted
            foreach (var appCert in m_appSelfSignedCerts)
            {
                var pemDataBlob = PEMWriter.ExportCertificateAsPEM(appCert);
                var pemString   = Encoding.UTF8.GetString(pemDataBlob);
                TestContext.Out.WriteLine(pemString);
#if NETCOREAPP3_1
                var exception = Assert.Throws <ArgumentException>(() => { CertificateFactory.CreateCertificateWithPEMPrivateKey(new X509Certificate2(appCert), pemDataBlob); });
#endif
            }
        }
Beispiel #3
0
        public void UpdateCertificateSelfSigned(string keyFormat)
        {
            ConnectPushClient(true);
            var keyFormats = _pushClient.PushClient.GetSupportedKeyFormats();

            if (!keyFormats.Contains(keyFormat))
            {
                Assert.Ignore("Push server doesn't support {0} key update", keyFormat);
            }

            X509Certificate2 newCert = CertificateFactory.CreateCertificate(
                null, null, null,
                _applicationRecord.ApplicationUri,
                _applicationRecord.ApplicationNames[0].Text,
                _selfSignedServerCert.Subject,
                null,
                CertificateFactory.DefaultKeySize,
                DateTime.UtcNow,
                CertificateFactory.DefaultLifeTime,
                CertificateFactory.DefaultHashSize);

            byte[] privateKey = null;
            if (keyFormat == "PFX")
            {
                Assert.IsTrue(newCert.HasPrivateKey);
                privateKey = newCert.Export(X509ContentType.Pfx);
            }
            else if (keyFormat == "PEM")
            {
                Assert.IsTrue(newCert.HasPrivateKey);
                privateKey = PEMWriter.ExportPrivateKeyAsPEM(newCert);
            }
            else
            {
                Assert.Fail("Testing unsupported key format {0}.", keyFormat);
            }

            var success = _pushClient.PushClient.UpdateCertificate(
                _pushClient.PushClient.DefaultApplicationGroup,
                _pushClient.PushClient.ApplicationCertificateType,
                newCert.RawData,
                keyFormat,
                privateKey,
                null);

            if (success)
            {
                _pushClient.PushClient.ApplyChanges();
            }
            VerifyNewPushServerCert(newCert.RawData);
        }
Beispiel #4
0
 public void VerifyPemWriterPrivateKeys()
 {
     // all app certs are trusted
     foreach (var appCert in m_appSelfSignedCerts)
     {
         var pemDataBlob = PEMWriter.ExportPrivateKeyAsPEM(appCert);
         var pemString   = Encoding.UTF8.GetString(pemDataBlob);
         TestContext.Out.WriteLine(pemString);
         CertificateFactory.CreateCertificateWithPEMPrivateKey(new X509Certificate2(appCert.RawData), pemDataBlob);
         // note: password is ignored
         var newCert = CertificateFactory.CreateCertificateWithPEMPrivateKey(new X509Certificate2(appCert.RawData), pemDataBlob, "password");
         X509Utils.VerifyRSAKeyPair(newCert, newCert, true);
     }
 }
Beispiel #5
0
        private void CheckPEMWriter(X509Certificate2 certificate, string password = null)
        {
            PEMWriter.ExportCertificateAsPEM(certificate);
            if (certificate.HasPrivateKey)
            {
#if NETFRAMEWORK || NETCOREAPP2_1
                // The implementation based on bouncy castle has no support to export with password
                password = null;
#endif
                PEMWriter.ExportPrivateKeyAsPEM(certificate, password);
#if NETCOREAPP3_1_OR_GREATER
                PEMWriter.ExportRSAPrivateKeyAsPEM(certificate);
#endif
            }
        }
Beispiel #6
0
 public void VerifyPemWriterPasswordPrivateKeys()
 {
     // all app certs are trusted
     foreach (var appCert in m_appSelfSignedCerts)
     {
         var password = Guid.NewGuid().ToString().Substring(0, 8);
         TestContext.Out.WriteLine("Password: {0}", password);
         var pemDataBlob = PEMWriter.ExportPrivateKeyAsPEM(appCert, password);
         var pemString   = Encoding.UTF8.GetString(pemDataBlob);
         TestContext.Out.WriteLine(pemString);
         var newCert   = CertificateFactory.CreateCertificateWithPEMPrivateKey(new X509Certificate2(appCert), pemDataBlob, password);
         var exception = Assert.Throws <CryptographicException>(() => { CertificateFactory.CreateCertificateWithPEMPrivateKey(new X509Certificate2(appCert), pemDataBlob); });
         X509Utils.VerifyRSAKeyPair(newCert, newCert, true);
     }
 }
        /// <summary>
        /// Create a certificate with a new key pair signed by the CA of the cert group.
        /// </summary>
        /// <param name="application">The application record.</param>
        /// <param name="subjectName">The subject of the certificate.</param>
        /// <param name="domainNames">The domain names for the subject alt name extension.</param>
        /// <param name="privateKeyFormat">The private key format as PFX or PEM.</param>
        /// <param name="privateKeyPassword">A password for the private key.</param>
        public virtual async Task <X509Certificate2KeyPair> NewKeyPairRequestAsync(
            ApplicationRecordDataType application,
            string subjectName,
            string[] domainNames,
            string privateKeyFormat,
            string privateKeyPassword)
        {
            if (application == null)
            {
                throw new ArgumentNullException(nameof(application));
            }
            if (application.ApplicationUri == null)
            {
                throw new ArgumentNullException(nameof(application.ApplicationUri));
            }
            if (application.ApplicationNames == null)
            {
                throw new ArgumentNullException(nameof(application.ApplicationNames));
            }

            using (var signingKey = await LoadSigningKeyAsync(Certificate, string.Empty).ConfigureAwait(false))
                using (var certificate = CertificateFactory.CreateCertificate(
                           application.ApplicationUri,
                           application.ApplicationNames.Count > 0 ? application.ApplicationNames[0].Text : "ApplicationName",
                           subjectName,
                           domainNames)
                                         .SetIssuer(signingKey)
                                         .CreateForRSA())
                {
                    byte[] privateKey;
                    if (privateKeyFormat == "PFX")
                    {
                        privateKey = certificate.Export(X509ContentType.Pfx, privateKeyPassword);
                    }
                    else if (privateKeyFormat == "PEM")
                    {
                        privateKey = PEMWriter.ExportPrivateKeyAsPEM(certificate, privateKeyPassword);
                    }
                    else
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidArgument, "Invalid private key format");
                    }
                    return(new X509Certificate2KeyPair(new X509Certificate2(certificate.RawData), privateKeyFormat, privateKey));
                }
        }
 public virtual async Task <X509Certificate2KeyPair> NewKeyPairRequestAsync(
     ApplicationRecordDataType application,
     string subjectName,
     string[] domainNames,
     string privateKeyFormat,
     string privateKeyPassword)
 {
     using (var signingKey = await LoadSigningKeyAsync(Certificate, string.Empty))
         using (var certificate = CertificateFactory.CreateCertificate(
                    null, null, null,
                    application.ApplicationUri ?? "urn:ApplicationURI",
                    application.ApplicationNames.Count > 0 ? application.ApplicationNames[0].Text : "ApplicationName",
                    subjectName,
                    domainNames,
                    Configuration.DefaultCertificateKeySize,
                    DateTime.UtcNow.AddDays(-1),
                    Configuration.DefaultCertificateLifetime,
                    Configuration.DefaultCertificateHashSize,
                    false,
                    signingKey,
                    null))
         {
             byte[] privateKey;
             if (privateKeyFormat == "PFX")
             {
                 privateKey = certificate.Export(X509ContentType.Pfx, privateKeyPassword);
             }
             else if (privateKeyFormat == "PEM")
             {
                 privateKey = PEMWriter.ExportPrivateKeyAsPEM(certificate);
             }
             else
             {
                 throw new ServiceResultException(StatusCodes.BadInvalidArgument, "Invalid private key format");
             }
             return(new X509Certificate2KeyPair(new X509Certificate2(certificate.RawData), privateKeyFormat, privateKey));
         }
 }
Beispiel #9
0
        private async void CertificateRequestTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                NodeId requestId = NodeId.Parse(m_application.CertificateRequestId);

                byte[]   privateKeyPFX      = null;
                byte[][] issuerCertificates = null;

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

                if (certificate == null)
                {
                    // request not done yet, try again in a few seconds
                    return;
                }

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

                if (m_application.RegistrationType != RegistrationType.ServerPush)
                {
                    X509Certificate2 newCert = new X509Certificate2(certificate);

                    if (!String.IsNullOrEmpty(m_application.CertificateStorePath) && !String.IsNullOrEmpty(m_application.CertificateSubjectName))
                    {
                        CertificateIdentifier cid = new CertificateIdentifier()
                        {
                            StorePath   = m_application.CertificateStorePath,
                            StoreType   = CertificateStoreIdentifier.DetermineStoreType(m_application.CertificateStorePath),
                            SubjectName = m_application.CertificateSubjectName.Replace("localhost", Utils.GetHostName())
                        };

                        // update store
                        using (var store = CertificateStoreIdentifier.OpenStore(m_application.CertificateStorePath))
                        {
                            // if we used a CSR, we already have a private key and therefore didn't request one from the GDS
                            // in this case, privateKey is null
                            if (privateKeyPFX == null)
                            {
                                X509Certificate2 oldCertificate = await cid.Find(true);

                                if (oldCertificate != null && oldCertificate.HasPrivateKey)
                                {
                                    oldCertificate = await cid.LoadPrivateKey(string.Empty);

                                    newCert = CertificateFactory.CreateCertificateWithPrivateKey(newCert, oldCertificate);
                                    await store.Delete(oldCertificate.Thumbprint);
                                }
                                else
                                {
                                    throw new ServiceResultException("Failed to merge signed certificate with the private key.");
                                }
                            }
                            else
                            {
                                newCert = new X509Certificate2(privateKeyPFX, string.Empty, X509KeyStorageFlags.Exportable);
                                newCert = CertificateFactory.Load(newCert, true);
                            }

                            await store.Add(newCert);
                        }
                    }
                    else
                    {
                        DialogResult result = DialogResult.Yes;
                        string       absoluteCertificatePublicKeyPath = Utils.GetAbsoluteFilePath(m_application.CertificatePublicKeyPath, true, false, false) ?? m_application.CertificatePublicKeyPath;
                        FileInfo     file = new FileInfo(absoluteCertificatePublicKeyPath);
                        if (file.Exists)
                        {
                            result = MessageBox.Show(
                                Parent,
                                "Replace certificate " +
                                absoluteCertificatePublicKeyPath +
                                "?",
                                Parent.Text,
                                MessageBoxButtons.YesNo,
                                MessageBoxIcon.Exclamation);
                        }

                        if (result == DialogResult.Yes)
                        {
                            byte[] exportedCert;
                            if (string.Compare(file.Extension, ".PEM", true) == 0)
                            {
                                exportedCert = PEMWriter.ExportCertificateAsPEM(newCert);
                            }
                            else
                            {
                                exportedCert = newCert.Export(X509ContentType.Cert);
                            }
                            File.WriteAllBytes(absoluteCertificatePublicKeyPath, exportedCert);
                        }

                        // if we provided a PFX or P12 with the private key, we need to merge the new cert with the private key
                        if (m_application.GetPrivateKeyFormat(m_server?.GetSupportedKeyFormats()) == "PFX")
                        {
                            string absoluteCertificatePrivateKeyPath = Utils.GetAbsoluteFilePath(m_application.CertificatePrivateKeyPath, true, false, false) ?? m_application.CertificatePrivateKeyPath;
                            file = new FileInfo(absoluteCertificatePrivateKeyPath);
                            if (file.Exists)
                            {
                                result = MessageBox.Show(
                                    Parent,
                                    "Replace private key " +
                                    absoluteCertificatePrivateKeyPath +
                                    "?",
                                    Parent.Text,
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Exclamation);
                            }

                            if (result == DialogResult.Yes)
                            {
                                if (file.Exists)
                                {
                                    byte[]           pkcsData       = File.ReadAllBytes(absoluteCertificatePrivateKeyPath);
                                    X509Certificate2 oldCertificate = X509PfxUtils.CreateCertificateFromPKCS12(pkcsData, m_certificatePassword);
                                    newCert  = CertificateFactory.CreateCertificateWithPrivateKey(newCert, oldCertificate);
                                    pkcsData = newCert.Export(X509ContentType.Pfx, m_certificatePassword);
                                    File.WriteAllBytes(absoluteCertificatePrivateKeyPath, pkcsData);

                                    if (privateKeyPFX != null)
                                    {
                                        throw new ServiceResultException("Did not expect a private key for this operation.");
                                    }
                                }
                                else
                                {
                                    File.WriteAllBytes(absoluteCertificatePrivateKeyPath, privateKeyPFX);
                                }
                            }
                        }
                    }

                    // update trust list.
                    if (!String.IsNullOrEmpty(m_application.TrustListStorePath))
                    {
                        using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_application.TrustListStorePath))
                        {
                            foreach (byte[] issuerCertificate in issuerCertificates)
                            {
                                X509Certificate2           x509  = new X509Certificate2(issuerCertificate);
                                X509Certificate2Collection certs = await store.FindByThumbprint(x509.Thumbprint);

                                if (certs.Count == 0)
                                {
                                    await store.Add(new X509Certificate2(issuerCertificate));
                                }
                            }
                        }
                    }

                    m_certificate = newCert;
                }
                else
                {
                    if (privateKeyPFX != null && privateKeyPFX.Length > 0)
                    {
                        var x509 = new X509Certificate2(privateKeyPFX, m_certificatePassword, X509KeyStorageFlags.Exportable);
                        privateKeyPFX = x509.Export(X509ContentType.Pfx);
                    }
                    bool applyChanges = m_server.UpdateCertificate(
                        null,
                        m_server.ApplicationCertificateType,
                        certificate,
                        (privateKeyPFX != null) ? "PFX" : null,
                        privateKeyPFX,
                        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;
                    }
                }

                CertificateControl.ShowValue(null, "Application Certificate", new CertificateWrapper()
                {
                    Certificate = m_certificate
                }, true);
            }
            catch (Exception exception)
            {
                if (exception is ServiceResultException sre && sre.StatusCode == StatusCodes.BadNothingToDo)
                {
                    return;
                }

                RequestProgressLabel.Visible    = false;
                CertificateRequestTimer.Enabled = false;
                Opc.Ua.Client.Controls.ExceptionDlg.Show(Text, exception);
            }
        }
Beispiel #10
0
 public void ExportPrivateKeyAsPEM()
 {
     _ = PEMWriter.ExportPrivateKeyAsPEM(m_certificate);
 }
Beispiel #11
0
 public void ExportCertificateAsPEM()
 {
     _ = PEMWriter.ExportCertificateAsPEM(m_certificate);
 }