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)); } }
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)); } }
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)); } }
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); }
private static SafeCertContextHandle GetCertificateContext(X509Certificate certificate) { SafeCertContextHandle certificateContext = X509Native.DuplicateCertContext(certificate.Handle); // Make sure to keep the X509Certificate object alive until after its certificate context is // duplicated, otherwise it could end up being closed out from underneath us before we get a // chance to duplicate the handle. GC.KeepAlive(certificate); return(certificateContext); }
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); } } }
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)); }