public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, ECDsa privateKey)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }
            if (privateKey == null)
            {
                throw new ArgumentNullException(nameof(privateKey));
            }

            if (certificate.HasPrivateKey)
            {
                throw new InvalidOperationException(SR.GetString(SR.Cryptography_Cert_AlreadyHasPrivateKey));
            }

            using (ECDsa publicKey = GetECDsaPublicKey(certificate))
            {
                if (publicKey == null)
                {
                    throw new ArgumentException(SR.GetString(SR.Cryptography_PrivateKey_WrongAlgorithm));
                }

                if (!IsSameKey(publicKey, privateKey))
                {
                    throw new ArgumentException(SR.GetString(SR.Cryptography_PrivateKey_DoesNotMatch), nameof(privateKey));
                }
            }

            ECDsaCng         ecdsaCng = privateKey as ECDsaCng;
            X509Certificate2 newCert  = null;

            if (ecdsaCng != null)
            {
                newCert = CertificateExtensionsCommon.CopyWithPersistedCngKey(certificate, ecdsaCng.Key);
            }

            // No CAPI option for ECDSA

            if (newCert == null)
            {
                ECParameters parameters = privateKey.ExportParameters(true);

                using (PinAndClear.Track(parameters.D))
                    using (ecdsaCng = new ECDsaCng())
                    {
                        ecdsaCng.ImportParameters(parameters);

                        newCert = CertificateExtensionsCommon.CopyWithEphemeralCngKey(certificate, ecdsaCng.Key);
                    }
            }

            Debug.Assert(newCert != null);
            Debug.Assert(!ReferenceEquals(certificate, newCert));
            Debug.Assert(!certificate.HasPrivateKey);
            Debug.Assert(newCert.HasPrivateKey);
            return(newCert);
        }
예제 #2
0
        public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, DSA privateKey)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }
            if (privateKey == null)
            {
                throw new ArgumentNullException(nameof(privateKey));
            }

            if (certificate.HasPrivateKey)
            {
                throw new InvalidOperationException(SR.GetString(SR.Cryptography_Cert_AlreadyHasPrivateKey));
            }

            using (DSA publicKey = GetDSAPublicKey(certificate))
            {
                if (publicKey == null)
                {
                    throw new ArgumentException(SR.GetString(SR.Cryptography_PrivateKey_WrongAlgorithm));
                }

                DSAParameters currentParameters = publicKey.ExportParameters(false);
                DSAParameters newParameters     = privateKey.ExportParameters(false);

                if (!currentParameters.G.SequenceEqual(newParameters.G) ||
                    !currentParameters.P.SequenceEqual(newParameters.P) ||
                    !currentParameters.Q.SequenceEqual(newParameters.Q) ||
                    !currentParameters.Y.SequenceEqual(newParameters.Y))
                {
                    throw new ArgumentException(SR.GetString(SR.Cryptography_PrivateKey_DoesNotMatch), nameof(privateKey));
                }
            }

            DSACng           dsaCng  = privateKey as DSACng;
            X509Certificate2 newCert = null;

            if (dsaCng != null)
            {
                newCert = CertificateExtensionsCommon.CopyWithPersistedCngKey(certificate, dsaCng.Key);
            }

            if (newCert == null)
            {
                DSACryptoServiceProvider dsaCsp = privateKey as DSACryptoServiceProvider;

                if (dsaCsp != null)
                {
                    newCert = CertificateExtensionsCommon.CopyWithPersistedCapiKey(certificate, dsaCsp.CspKeyContainerInfo);
                }
            }

            if (newCert == null)
            {
                DSAParameters parameters = privateKey.ExportParameters(true);

                using (PinAndClear.Track(parameters.X))
                    using (dsaCng = new DSACng())
                    {
                        dsaCng.ImportParameters(parameters);

                        newCert = CertificateExtensionsCommon.CopyWithEphemeralCngKey(certificate, dsaCng.Key);
                    }
            }

            Debug.Assert(newCert != null);
            Debug.Assert(!ReferenceEquals(certificate, newCert));
            Debug.Assert(!certificate.HasPrivateKey);
            Debug.Assert(newCert.HasPrivateKey);
            return(newCert);
        }