/// <summary>
        /// Create a X509Certificate2 with a private key by combining
        /// the certificate with a private key from a PEM stream
        /// </summary>
        public static X509Certificate2 CreateCertificateWithPEMPrivateKey(
            X509Certificate2 certificate,
            byte[] pemDataBlob,
            string password = null)
        {
            RSA privateKey = PEMReader.ImportPrivateKeyFromPEM(pemDataBlob, password);

            if (privateKey == null)
            {
                throw new ServiceResultException("PEM data blob does not contain a private key.");
            }

            string passcode = X509Utils.GeneratePasscode();

            byte[] pfxData = CertificateBuilder.CreatePfxWithRSAPrivateKey(
                certificate, certificate.FriendlyName, privateKey, passcode);
            return(X509Utils.CreateCertificateFromPKCS12(pfxData, passcode));
        }
Beispiel #2
0
        /// <inheritdoc/>
        public Task Add(X509Certificate2 certificate, string password = null)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            using (X509Store store = new X509Store(m_storeName, m_storeLocation))
            {
                store.Open(OpenFlags.ReadWrite);
                if (!store.Certificates.Contains(certificate))
                {
#if NETSTANDARD2_1 || NET5_0_OR_GREATER || NET472_OR_GREATER
                    if (certificate.HasPrivateKey && !m_noPrivateKeys &&
                        (Environment.OSVersion.Platform == PlatformID.Win32NT))
                    {
                        // see https://github.com/dotnet/runtime/issues/29144
                        var temp = X509Utils.GeneratePasscode();
                        using (var persistable = new X509Certificate2(certificate.Export(X509ContentType.Pfx, temp), temp,
                                                                      X509KeyStorageFlags.PersistKeySet))
                        {
                            store.Add(persistable);
                        }
                    }
                    else
#endif
                    if (certificate.HasPrivateKey && m_noPrivateKeys)
                    {
                        // ensure no private key is added to store
                        store.Add(new X509Certificate2(certificate.RawData));
                    }
                    else
                    {
                        store.Add(certificate);
                    }

                    Utils.LogCertificate("Added certificate to X509Store {0}.", certificate, store.Name);
                }
            }

            return(Task.CompletedTask);
        }
        /// <summary>
        /// Create a X509Certificate2 with a private key by combining
        /// the new certificate with a private key from an existing certificate
        /// </summary>
        public static X509Certificate2 CreateCertificateWithPrivateKey(
            X509Certificate2 certificate,
            X509Certificate2 certificateWithPrivateKey)
        {
            if (!certificateWithPrivateKey.HasPrivateKey)
            {
                throw new NotSupportedException("Need a certificate with a private key.");
            }

            if (!X509Utils.VerifyRSAKeyPair(certificate, certificateWithPrivateKey))
            {
                throw new NotSupportedException("The public and the private key pair doesn't match.");
            }

            string passcode = X509Utils.GeneratePasscode();

            using (RSA rsaPrivateKey = certificateWithPrivateKey.GetRSAPrivateKey())
            {
                byte[] pfxData = CertificateBuilder.CreatePfxWithRSAPrivateKey(
                    certificate, certificate.FriendlyName, rsaPrivateKey, passcode);
                return(X509Utils.CreateCertificateFromPKCS12(pfxData, passcode));
            }
        }