private ICertificatePal CopyWithEphemeralKey(CngKey cngKey) { Debug.Assert(string.IsNullOrEmpty(cngKey.KeyName)); // Handle makes a copy of the handle. This is required given that CertSetCertificateContextProperty accepts a SafeHandle // and transfers ownership of the handle to the certificate. We can't transfer that ownership out of the cngKey, as it's // owned by the caller, so we make a copy (using Handle rather than HandleNoDuplicate). using (SafeNCryptKeyHandle handle = cngKey.Handle) { // Make a new pal from bytes. CertificatePal pal = (CertificatePal)FromBlob(RawData, SafePasswordHandle.InvalidHandle, X509KeyStorageFlags.PersistKeySet); try { if (!Interop.Crypt32.CertSetCertificateContextProperty( pal._certContext, Interop.Crypt32.CertContextPropId.CERT_NCRYPT_KEY_HANDLE_PROP_ID, Interop.Crypt32.CertSetPropertyFlags.CERT_SET_PROPERTY_INHIBIT_PERSIST_FLAG, handle)) { throw Marshal.GetLastPInvokeError().ToCryptographicException(); } // The value was transferred to the certificate. handle.SetHandleAsInvalid(); return(pal); } catch { pal.Dispose(); throw; } } }
private unsafe ICertificatePal?CopyWithPersistedCapiKey(CspKeyContainerInfo keyContainerInfo) { if (string.IsNullOrEmpty(keyContainerInfo.KeyContainerName)) { return(null); } // Make a new pal from bytes. CertificatePal pal = (CertificatePal)FromBlob(RawData, SafePasswordHandle.InvalidHandle, X509KeyStorageFlags.PersistKeySet); Interop.Crypt32.CRYPT_KEY_PROV_INFO keyProvInfo = default; fixed(char *keyName = keyContainerInfo.KeyContainerName) fixed(char *provName = keyContainerInfo.ProviderName) { keyProvInfo.pwszContainerName = keyName; keyProvInfo.pwszProvName = provName; keyProvInfo.dwFlags = keyContainerInfo.MachineKeyStore ? Interop.Crypt32.CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET : 0; keyProvInfo.dwProvType = keyContainerInfo.ProviderType; keyProvInfo.dwKeySpec = (int)keyContainerInfo.KeyNumber; if (!Interop.Crypt32.CertSetCertificateContextProperty( pal._certContext, Interop.Crypt32.CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, Interop.Crypt32.CertSetPropertyFlags.None, &keyProvInfo)) { Exception e = Marshal.GetLastPInvokeError().ToCryptographicException(); pal.Dispose(); throw e; } } return(pal); }
private unsafe ICertificatePal?CopyWithPersistedCngKey(CngKey cngKey) { if (string.IsNullOrEmpty(cngKey.KeyName)) { return(null); } // Make a new pal from bytes. CertificatePal pal = (CertificatePal)FromBlob(RawData, SafePasswordHandle.InvalidHandle, X509KeyStorageFlags.PersistKeySet); 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); Interop.Crypt32.CRYPT_KEY_PROV_INFO keyProvInfo = default; fixed(char *keyNamePtr = cngKey.KeyName) fixed(char *provNamePtr = cngKey.Provider !.Provider) { keyProvInfo.pwszContainerName = keyNamePtr; keyProvInfo.pwszProvName = provNamePtr; keyProvInfo.dwFlags = machineKey ? Interop.Crypt32.CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET : 0; keyProvInfo.dwKeySpec = keySpec; if (!Interop.Crypt32.CertSetCertificateContextProperty( pal._certContext, Interop.Crypt32.CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, Interop.Crypt32.CertSetPropertyFlags.None, &keyProvInfo)) { Exception e = Marshal.GetLastPInvokeError().ToCryptographicException(); pal.Dispose(); throw e; } } return(pal); }
private ICertificatePal CopyWithEphemeralKey(CngKey cngKey) { Debug.Assert(string.IsNullOrEmpty(cngKey.KeyName)); SafeNCryptKeyHandle handle = cngKey.Handle; // Make a new pal from bytes. CertificatePal pal = (CertificatePal)FromBlob(RawData, SafePasswordHandle.InvalidHandle, X509KeyStorageFlags.PersistKeySet); if (!Interop.Crypt32.CertSetCertificateContextProperty( pal._certContext, Interop.Crypt32.CertContextPropId.CERT_NCRYPT_KEY_HANDLE_PROP_ID, Interop.Crypt32.CertSetPropertyFlags.CERT_SET_PROPERTY_INHIBIT_PERSIST_FLAG, handle)) { pal.Dispose(); throw Marshal.GetLastWin32Error().ToCryptographicException(); } // The value was transferred to the certificate. handle.SetHandleAsInvalid(); return(pal); }