Ejemplo n.º 1
0
        public static RSA GetRSAPrivateKey(this X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }

            if (!certificate.HasPrivateKey || !IsRSA(certificate))
            {
                return(null);
            }

            using (SafeCertContextHandle certificateContext = X509Native.GetCertificateContext(certificate))
                using (SafeNCryptKeyHandle privateKeyHandle = X509Native.TryAcquireCngPrivateKey(certificateContext))
                {
                    if (privateKeyHandle == null)
                    {
                        // fall back to CAPI if we cannot acquire the key using CNG.
                        return((RSA)certificate.PrivateKey);
                    }

                    CngKey key = CngKey.Open(privateKeyHandle, CngKeyHandleOpenOptions.None);
                    return(new RSACng(key));
                }
        }
Ejemplo n.º 2
0
        public static DSA GetDSAPrivateKey(this X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }

            if (!certificate.HasPrivateKey || !IsDSA(certificate))
            {
                return(null);
            }

            CngKeyHandleOpenOptions openOptions;

            using (SafeCertContextHandle certificateContext = X509Native.GetCertificateContext(certificate))
                using (SafeNCryptKeyHandle privateKeyHandle = X509Native.TryAcquireCngPrivateKey(certificateContext, out openOptions))
                {
                    if (privateKeyHandle == null)
                    {
                        // fall back to CAPI if we cannot acquire the key using CNG.
                        DSACryptoServiceProvider dsaCsp        = (DSACryptoServiceProvider)certificate.PrivateKey;
                        CspParameters            cspParameters = CopyCspParameters(dsaCsp);
                        DSACryptoServiceProvider clone         = new DSACryptoServiceProvider(cspParameters);
                        return(clone);
                    }

                    CngKey key = CngKey.Open(privateKeyHandle, openOptions);
                    return(new DSACng(key));
                }
        }
Ejemplo n.º 3
0
        public static RSA GetRSAPrivateKey(this X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }

            if (!certificate.HasPrivateKey || !IsRSA(certificate))
            {
                return(null);
            }

            using (SafeCertContextHandle certificateContext = X509Native.GetCertificateContext(certificate))
                using (SafeNCryptKeyHandle privateKeyHandle = X509Native.TryAcquireCngPrivateKey(certificateContext))
                {
                    if (privateKeyHandle == null)
                    {
                        if (LocalAppContextSwitches.DontReliablyClonePrivateKey)
                        {
                            return((RSA)certificate.PrivateKey);
                        }

                        // fall back to CAPI if we cannot acquire the key using CNG.
                        RSACryptoServiceProvider rsaCsp        = (RSACryptoServiceProvider)certificate.PrivateKey;
                        CspParameters            cspParameters = DSACertificateExtensions.CopyCspParameters(rsaCsp);
                        RSACryptoServiceProvider clone         = new RSACryptoServiceProvider(cspParameters);
                        return(clone);
                    }

                    CngKey key = CngKey.Open(privateKeyHandle, CngKeyHandleOpenOptions.None);
                    return(new RSACng(key));
                }
        }
        internal static X509Certificate2 CopyWithPersistedCapiKey(X509Certificate2 publicCert, CspKeyContainerInfo keyContainerInfo)
        {
            if (string.IsNullOrEmpty(keyContainerInfo.KeyContainerName))
            {
                return(null);
            }

            X509Certificate2 publicPrivate = new X509Certificate2(publicCert.RawData);

            var keyProvInfo = new X509Native.CRYPT_KEY_PROV_INFO();

            keyProvInfo.pwszContainerName = keyContainerInfo.KeyContainerName;
            keyProvInfo.pwszProvName      = keyContainerInfo.ProviderName;
            keyProvInfo.dwProvType        = keyContainerInfo.ProviderType;
            keyProvInfo.dwKeySpec         = (int)keyContainerInfo.KeyNumber;
            keyProvInfo.dwFlags           = keyContainerInfo.MachineKeyStore ? X509Native.CRYPT_MACHINE_KEYSET : 0;

            using (SafeCertContextHandle certificateContext = X509Native.GetCertificateContext(publicPrivate))
            {
                if (!X509Native.SetCertificateKeyProvInfo(certificateContext, ref keyProvInfo))
                {
                    int hr = Marshal.GetLastWin32Error();
                    publicPrivate.Dispose();
                    throw new CryptographicException(hr);
                }
            }

            return(publicPrivate);
        }
        internal static X509Certificate2 CopyWithPersistedCngKey(X509Certificate2 publicCert, CngKey cngKey)
        {
            if (string.IsNullOrEmpty(cngKey.KeyName))
            {
                return(null);
            }

            X509Certificate2 publicPrivate = new X509Certificate2(publicCert.RawData);
            CngProvider      provider      = cngKey.Provider;
            string           keyName       = cngKey.KeyName;
            bool             machineKey    = cngKey.IsMachineKey;

            // CAPI RSA_SIGN keys won't open correctly under CNG without the key number being specified, so
            // check to see if we can figure out what key number it needs to re-open.
            int keySpec = GuessKeySpec(provider, keyName, machineKey, cngKey.AlgorithmGroup);

            var keyProvInfo = new X509Native.CRYPT_KEY_PROV_INFO();

            keyProvInfo.pwszContainerName = cngKey.KeyName;
            keyProvInfo.pwszProvName      = cngKey.Provider.Provider;
            keyProvInfo.dwFlags           = machineKey ? X509Native.CRYPT_MACHINE_KEYSET : 0;
            keyProvInfo.dwKeySpec         = keySpec;

            using (SafeCertContextHandle certificateContext = X509Native.GetCertificateContext(publicPrivate))
            {
                if (!X509Native.SetCertificateKeyProvInfo(certificateContext, ref keyProvInfo))
                {
                    int hr = Marshal.GetLastWin32Error();
                    publicPrivate.Dispose();
                    throw new CryptographicException(hr);
                }
            }

            return(publicPrivate);
        }
        public static ECDsa GetECDsaPublicKey(this X509Certificate2 certificate)
        {
            if (LocalAppContextSwitches.UseLegacyPublicKeyBehavior)
            {
                return(LegacyGetECDsaPublicKey(certificate));
            }

            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }
            if (!IsECDsa(certificate))
            {
                return(null);
            }

            using (SafeCertContextHandle safeCertContext = X509Native.GetCertificateContext(certificate))
                using (SafeBCryptKeyHandle bcryptKeyHandle = ImportPublicKeyInfo(safeCertContext))
                {
                    if (bcryptKeyHandle.IsInvalid)
                    {
                        throw new CryptographicException("SR.GetString(SR.Cryptography_OpenInvalidHandle)");
                    }

                    string curveName = GetCurveName(bcryptKeyHandle);

                    if (curveName == null)
                    {
                        CngKeyBlobFormat blobFormat = HasExplicitParameters(bcryptKeyHandle) ?
                                                      CngKeyBlobFormat.EccFullPublicBlob : CngKeyBlobFormat.EccPublicBlob;

                        byte[] keyBlob = BCryptNative.ExportBCryptKey(bcryptKeyHandle, blobFormat.Format);
                        using (CngKey key = CngKey.Import(keyBlob, blobFormat))
                        {
                            return(new ECDsaCng(key));
                        }
                    }
                    else
                    {
                        CngKeyBlobFormat blobFormat = CngKeyBlobFormat.EccPublicBlob;
                        byte[]           keyBlob    = BCryptNative.ExportBCryptKey(bcryptKeyHandle, blobFormat.Format);
                        ECParameters     ecparams   = new ECParameters();
                        ExportNamedCurveParameters(ref ecparams, keyBlob, false);
                        ecparams.Curve = ECCurve.CreateFromFriendlyName(curveName);
                        ECDsaCng ecdsa = new ECDsaCng();
                        ecdsa.ImportParameters(ecparams);

                        return(ecdsa);
                    }
                }
        }
Ejemplo n.º 7
0
        public static ECDsa GetECDsaPrivateKey(this X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }
            //Check cert for private key and confirm it is ECDSA cert
            if (!certificate.HasPrivateKey || !IsECDsa(certificate))
            {
                return(null);
            }

            using (SafeCertContextHandle certificateContext = X509Native.GetCertificateContext(certificate))
                using (SafeNCryptKeyHandle privateKeyHandle = X509Native.TryAcquireCngPrivateKey(certificateContext))
                {
                    CngKey key = CngKey.Open(privateKeyHandle, CngKeyHandleOpenOptions.None);
                    return(new ECDsaCng(key));
                }
        }
        internal static X509Certificate2 CopyWithEphemeralCngKey(X509Certificate2 publicCert, CngKey cngKey)
        {
            Debug.Assert(string.IsNullOrEmpty(cngKey.KeyName));

            X509Certificate2    publicPrivate = new X509Certificate2(publicCert.RawData);
            SafeNCryptKeyHandle handle        = cngKey.Handle;

            using (SafeCertContextHandle certificateContext = X509Native.GetCertificateContext(publicPrivate))
            {
                if (!X509Native.SetCertificateNCryptKeyHandle(certificateContext, handle))
                {
                    int hr = Marshal.GetLastWin32Error();
                    publicPrivate.Dispose();
                    throw new CryptographicException(hr);
                }
            }

            // The value was transferred to the certificate.
            handle.SetHandleAsInvalid();
            return(publicPrivate);
        }
        private static ECDsa LegacyGetECDsaPublicKey(X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }
            if (!IsECDsa(certificate))
            {
                return(null);
            }

            SafeCertContextHandle safeCertContext = X509Native.GetCertificateContext(certificate);
            IntPtr certHandle = safeCertContext.DangerousGetHandle();

            //Read the public key blob from the certificate
            X509Native.CERT_CONTEXT pCertContext = (X509Native.CERT_CONTEXT)Marshal.PtrToStructure(certHandle, typeof(X509Native.CERT_CONTEXT));

            IntPtr pSubjectPublicKeyInfo = new IntPtr((long)pCertContext.pCertInfo +
                                                      (long)Marshal.OffsetOf(typeof(X509Native.CERT_INFO), "SubjectPublicKeyInfo"));

            X509Native.CERT_PUBLIC_KEY_INFO certPublicKeyInfo = (X509Native.CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure(pSubjectPublicKeyInfo,
                                                                                                                        typeof(X509Native.CERT_PUBLIC_KEY_INFO));
            CngKey key;

            //Import the public key blob to BCRYPT_KEY_HANDLE
            using (SafeBCryptKeyHandle bcryptKeyHandle = BCryptNative.ImportAsymmetricPublicKey(certPublicKeyInfo, 0))
            {
                if (bcryptKeyHandle.IsInvalid)
                {
                    throw new CryptographicException("SR.GetString(SR.Cryptography_OpenInvalidHandle)");
                }
                key = LegacyBCryptHandleToNCryptHandle(bcryptKeyHandle);
            }
            GC.KeepAlive(safeCertContext);
            return(new ECDsaCng(key));
        }