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); }
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); }