public ICertificatePal CopyWithPrivateKey(ECDiffieHellman privateKey)
        {
            var typedKey = privateKey as ECDiffieHellmanImplementation.ECDiffieHellmanSecurityTransforms;

            byte[] ecPrivateKey;

            if (typedKey != null)
            {
                ECParameters ecParameters = default;

                if (typedKey.TryExportDataKeyParameters(includePrivateParameters: true, ref ecParameters))
                {
                    using (PinAndClear.Track(ecParameters.D !))
                    {
                        AsnWriter writer = EccKeyFormatHelper.WriteECPrivateKey(ecParameters);
                        ecPrivateKey = writer.Encode();
                        writer.Reset();
                    }
                }
                else
                {
                    return(CopyWithPrivateKey(typedKey.GetKeys().PrivateKey));
                }
            }
            else
            {
                ecPrivateKey = privateKey.ExportECPrivateKey();
            }

            using (PinAndClear.Track(ecPrivateKey))
                using (SafeSecKeyRefHandle privateSecKey = Interop.AppleCrypto.ImportEphemeralKey(ecPrivateKey, true))
                {
                    return(CopyWithPrivateKey(privateSecKey));
                }
        }
        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 ICertificatePal CopyWithPrivateKey(RSA privateKey)
        {
            var typedKey = privateKey as RSAImplementation.RSASecurityTransforms;

            if (typedKey != null)
            {
                return(CopyWithPrivateKey(typedKey.GetKeys().PrivateKey));
            }

            byte[] rsaPrivateKey = privateKey.ExportRSAPrivateKey();

            using (PinAndClear.Track(rsaPrivateKey))
                using (SafeSecKeyRefHandle privateSecKey = Interop.AppleCrypto.ImportEphemeralKey(rsaPrivateKey, true))
                {
                    return(CopyWithPrivateKey(privateSecKey));
                }
        }
예제 #4
0
        internal static SafeSecKeyRefHandle?GetPrivateKey(AsymmetricAlgorithm?key)
        {
            if (key == null)
            {
                return(null);
            }

            if (key is RSAImplementation.RSASecurityTransforms rsa)
            {
                // Convert data key to legacy CSSM key that can be imported into keychain
                byte[] rsaPrivateKey = rsa.ExportRSAPrivateKey();
                using (PinAndClear.Track(rsaPrivateKey))
                {
                    return(Interop.AppleCrypto.ImportEphemeralKey(rsaPrivateKey, true));
                }
            }

            if (key is DSAImplementation.DSASecurityTransforms dsa)
            {
                // DSA always uses legacy CSSM keys do no need to convert
                return(dsa.GetKeys().PrivateKey);
            }

            if (key is ECDsaImplementation.ECDsaSecurityTransforms ecdsa)
            {
                // Convert data key to legacy CSSM key that can be imported into keychain
                byte[] ecdsaPrivateKey = ecdsa.ExportECPrivateKey();
                using (PinAndClear.Track(ecdsaPrivateKey))
                {
                    return(Interop.AppleCrypto.ImportEphemeralKey(ecdsaPrivateKey, true));
                }
            }

            Debug.Fail("Invalid key implementation");
            return(null);
        }
예제 #5
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);
        }