internal static extern bool CryptAcquireCertificatePrivateKey( SafeCertContextHandle pCert, CryptAcquireCertificatePrivateKeyFlags dwFlags, IntPtr pvParameters, out IntPtr phCryptProvOrNCryptKey, out CryptKeySpec pdwKeySpec, out bool pfCallerFreeProvOrNCryptKey);
public static partial bool CryptAcquireCertificatePrivateKey( SafeCertContextHandle pCert, CryptAcquireCertificatePrivateKeyFlags dwFlags, IntPtr pvParameters, out SafeNCryptKeyHandle phCryptProvOrNCryptKey, out CryptKeySpec pdwKeySpec, [MarshalAs(UnmanagedType.Bool)] out bool pfCallerFreeProvOrNCryptKey);
private static Exception TryGetKeySpecForCertificate(X509Certificate2 cert, out CryptKeySpec keySpec) { using (SafeCertContextHandle hCertContext = cert.CreateCertContextHandle()) { int cbSize = 0; if (!Interop.Crypt32.CertGetCertificateContextProperty(hCertContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, null, ref cbSize)) { ErrorCode errorCode = (ErrorCode)(Marshal.GetLastWin32Error()); keySpec = default(CryptKeySpec); return(errorCode.ToCryptographicException()); } byte[] pData = new byte[cbSize]; unsafe { fixed(byte *pvData = pData) { if (!Interop.Crypt32.CertGetCertificateContextProperty(hCertContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, pData, ref cbSize)) { ErrorCode errorCode = (ErrorCode)(Marshal.GetLastWin32Error()); keySpec = default(CryptKeySpec); return(errorCode.ToCryptographicException()); } CRYPT_KEY_PROV_INFO *pCryptKeyProvInfo = (CRYPT_KEY_PROV_INFO *)pvData; keySpec = pCryptKeyProvInfo->dwKeySpec; return(null); } } } }
private static Exception TryGetKeySpecForCertificate(X509Certificate2 cert, out CryptKeySpec keySpec) { using (SafeCertContextHandle hCertContext = cert.CreateCertContextHandle()) { int cbSize = 0; if (!Interop.Crypt32.CertGetCertificateContextProperty(hCertContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, null, ref cbSize)) { ErrorCode errorCode = (ErrorCode)(Marshal.GetLastWin32Error()); keySpec = default(CryptKeySpec); return errorCode.ToCryptographicException(); } byte[] pData = new byte[cbSize]; unsafe { fixed (byte* pvData = pData) { if (!Interop.Crypt32.CertGetCertificateContextProperty(hCertContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, pData, ref cbSize)) { ErrorCode errorCode = (ErrorCode)(Marshal.GetLastWin32Error()); keySpec = default(CryptKeySpec); return errorCode.ToCryptographicException(); } CRYPT_KEY_PROV_INFO* pCryptKeyProvInfo = (CRYPT_KEY_PROV_INFO*)pvData; keySpec = pCryptKeyProvInfo->dwKeySpec; return null; } } } }
private Exception TryDecryptAgree(KeyAgreeRecipientInfo keyAgreeRecipientInfo, SafeProvOrNCryptKeyHandle hKey, CryptKeySpec keySpec, X509Certificate2Collection originatorCerts, X509Certificate2Collection extraStore) { unsafe { KeyAgreeRecipientInfoPalWindows pal = (KeyAgreeRecipientInfoPalWindows)(keyAgreeRecipientInfo.Pal); return(pal.WithCmsgCmsRecipientInfo <Exception>( delegate(CMSG_KEY_AGREE_RECIPIENT_INFO * pKeyAgreeRecipientInfo) { CMSG_CTRL_KEY_AGREE_DECRYPT_PARA decryptPara = default(CMSG_CTRL_KEY_AGREE_DECRYPT_PARA); decryptPara.cbSize = Marshal.SizeOf <CMSG_CTRL_KEY_AGREE_DECRYPT_PARA>(); decryptPara.hProv = hKey; decryptPara.dwKeySpec = keySpec; decryptPara.pKeyAgree = pKeyAgreeRecipientInfo; decryptPara.dwRecipientIndex = pal.Index; decryptPara.dwRecipientEncryptedKeyIndex = pal.SubIndex; CMsgKeyAgreeOriginatorChoice originatorChoice = pKeyAgreeRecipientInfo->dwOriginatorChoice; switch (originatorChoice) { case CMsgKeyAgreeOriginatorChoice.CMSG_KEY_AGREE_ORIGINATOR_CERT: { X509Certificate2Collection candidateCerts = new X509Certificate2Collection(); candidateCerts.AddRange(Helpers.GetStoreCertificates(StoreName.AddressBook, StoreLocation.CurrentUser, openExistingOnly: true)); candidateCerts.AddRange(Helpers.GetStoreCertificates(StoreName.AddressBook, StoreLocation.LocalMachine, openExistingOnly: true)); candidateCerts.AddRange(originatorCerts); candidateCerts.AddRange(extraStore); SubjectIdentifier originatorId = pKeyAgreeRecipientInfo->OriginatorCertId.ToSubjectIdentifier(); X509Certificate2 originatorCert = candidateCerts.TryFindMatchingCertificate(originatorId); if (originatorCert == null) { return ErrorCode.CRYPT_E_NOT_FOUND.ToCryptographicException(); } using (SafeCertContextHandle hCertContext = originatorCert.CreateCertContextHandle()) { CERT_CONTEXT *pOriginatorCertContext = hCertContext.DangerousGetCertContext(); decryptPara.OriginatorPublicKey = pOriginatorCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey; // Do not factor this call out of the switch statement as leaving this "using" block will free up // native memory that decryptPara points to. return TryExecuteDecryptAgree(ref decryptPara); } } case CMsgKeyAgreeOriginatorChoice.CMSG_KEY_AGREE_ORIGINATOR_PUBLIC_KEY: { decryptPara.OriginatorPublicKey = pKeyAgreeRecipientInfo->OriginatorPublicKeyInfo.PublicKey; return TryExecuteDecryptAgree(ref decryptPara); } default: return new CryptographicException(SR.Format(SR.Cryptography_Cms_Invalid_Originator_Identifier_Choice, originatorChoice)); } })); } }
private Exception TryDecryptTrans(KeyTransRecipientInfo recipientInfo, SafeProvOrNCryptKeyHandle hKey, CryptKeySpec keySpec) { KeyTransRecipientInfoPalWindows pal = (KeyTransRecipientInfoPalWindows)(recipientInfo.Pal); CMSG_CTRL_DECRYPT_PARA decryptPara; decryptPara.cbSize = Marshal.SizeOf <CMSG_CTRL_DECRYPT_PARA>(); decryptPara.hKey = hKey; decryptPara.dwKeySpec = keySpec; decryptPara.dwRecipientIndex = pal.Index; bool success = Interop.Crypt32.CryptMsgControl(_hCryptMsg, 0, MsgControlType.CMSG_CTRL_DECRYPT, ref decryptPara); if (!success) { return(Marshal.GetHRForLastWin32Error().ToCryptographicException()); } return(null); }
private unsafe Exception?TryDecryptTrans(KeyTransRecipientInfo recipientInfo, SafeProvOrNCryptKeyHandle hKey, CryptKeySpec keySpec) { KeyTransRecipientInfoPalWindows pal = (KeyTransRecipientInfoPalWindows)(recipientInfo.Pal); bool keyAddRefd = false; try { CMSG_CTRL_DECRYPT_PARA decryptPara; decryptPara.cbSize = sizeof(CMSG_CTRL_DECRYPT_PARA); hKey.DangerousAddRef(ref keyAddRefd); decryptPara.hKey = hKey.DangerousGetHandle(); decryptPara.dwKeySpec = keySpec; decryptPara.dwRecipientIndex = pal.Index; bool success = Interop.Crypt32.CryptMsgControl(_hCryptMsg, 0, MsgControlType.CMSG_CTRL_DECRYPT, ref decryptPara); if (!success) { return(Marshal.GetHRForLastWin32Error().ToCryptographicException()); } return(null); } finally { if (keyAddRefd) { hKey.DangerousRelease(); } } }
internal static SafeProvOrNCryptKeyHandle GetCertificatePrivateKey( X509Certificate2 cert, bool silent, bool preferNCrypt, out CryptKeySpec keySpec, out Exception exception) { CryptAcquireCertificatePrivateKeyFlags flags = CryptAcquireCertificatePrivateKeyFlags.CRYPT_ACQUIRE_USE_PROV_INFO_FLAG | CryptAcquireCertificatePrivateKeyFlags.CRYPT_ACQUIRE_COMPARE_KEY_FLAG; if (preferNCrypt) { flags |= CryptAcquireCertificatePrivateKeyFlags.CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG; } else { flags |= CryptAcquireCertificatePrivateKeyFlags.CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG; } if (silent) { flags |= CryptAcquireCertificatePrivateKeyFlags.CRYPT_ACQUIRE_SILENT_FLAG; } bool isNCrypt; bool mustFree; using (SafeCertContextHandle hCertContext = cert.CreateCertContextHandle()) { IntPtr hKey; int cbSize = IntPtr.Size; if (Interop.Crypt32.CertGetCertificateContextProperty( hCertContext, CertContextPropId.CERT_NCRYPT_KEY_HANDLE_PROP_ID, out hKey, ref cbSize)) { exception = null; keySpec = CryptKeySpec.CERT_NCRYPT_KEY_SPEC; return(new SafeProvOrNCryptKeyHandleUwp(hKey, hCertContext)); } if (!Interop.Crypt32.CryptAcquireCertificatePrivateKey( hCertContext, flags, IntPtr.Zero, out hKey, out keySpec, out mustFree)) { exception = Marshal.GetHRForLastWin32Error().ToCryptographicException(); return(null); } // We need to know whether we got back a CRYPTPROV or NCrypt handle. // Unfortunately, NCryptIsKeyHandle() is a prohibited api on UWP. // Fortunately, CryptAcquireCertificatePrivateKey() is documented to tell us which // one we got through the keySpec value. switch (keySpec) { case CryptKeySpec.AT_KEYEXCHANGE: case CryptKeySpec.AT_SIGNATURE: isNCrypt = false; break; case CryptKeySpec.CERT_NCRYPT_KEY_SPEC: isNCrypt = true; break; default: // As of this writing, we've exhausted all the known values of keySpec. // We have no idea what kind of key handle we got so play it safe and fail fast. throw new NotSupportedException(SR.Format(SR.Cryptography_Cms_UnknownKeySpec, keySpec)); } SafeProvOrNCryptKeyHandleUwp hProvOrNCryptKey = new SafeProvOrNCryptKeyHandleUwp( hKey, ownsHandle: mustFree, isNcrypt: isNCrypt); exception = null; return(hProvOrNCryptKey); } }
private Exception TryDecryptAgree(KeyAgreeRecipientInfo keyAgreeRecipientInfo, SafeProvOrNCryptKeyHandle hKey, CryptKeySpec keySpec, X509Certificate2Collection originatorCerts, X509Certificate2Collection extraStore) { unsafe { KeyAgreeRecipientInfoPalWindows pal = (KeyAgreeRecipientInfoPalWindows)(keyAgreeRecipientInfo.Pal); return pal.WithCmsgCmsRecipientInfo<Exception>( delegate (CMSG_KEY_AGREE_RECIPIENT_INFO* pKeyAgreeRecipientInfo) { CMSG_CTRL_KEY_AGREE_DECRYPT_PARA decryptPara = default(CMSG_CTRL_KEY_AGREE_DECRYPT_PARA); decryptPara.cbSize = Marshal.SizeOf<CMSG_CTRL_KEY_AGREE_DECRYPT_PARA>(); decryptPara.hProv = hKey; decryptPara.dwKeySpec = keySpec; decryptPara.pKeyAgree = pKeyAgreeRecipientInfo; decryptPara.dwRecipientIndex = pal.Index; decryptPara.dwRecipientEncryptedKeyIndex = pal.SubIndex; CMsgKeyAgreeOriginatorChoice originatorChoice = pKeyAgreeRecipientInfo->dwOriginatorChoice; switch (originatorChoice) { case CMsgKeyAgreeOriginatorChoice.CMSG_KEY_AGREE_ORIGINATOR_CERT: { X509Certificate2Collection candidateCerts = new X509Certificate2Collection(); candidateCerts.AddRange(Helpers.GetStoreCertificates(StoreName.AddressBook, StoreLocation.CurrentUser, openExistingOnly: true)); candidateCerts.AddRange(Helpers.GetStoreCertificates(StoreName.AddressBook, StoreLocation.LocalMachine, openExistingOnly: true)); candidateCerts.AddRange(originatorCerts); candidateCerts.AddRange(extraStore); SubjectIdentifier originatorId = pKeyAgreeRecipientInfo->OriginatorCertId.ToSubjectIdentifier(); using (X509Certificate2 originatorCert = candidateCerts.TryFindMatchingCertificate(originatorId)) { if (originatorCert == null) return ErrorCode.CRYPT_E_NOT_FOUND.ToCryptographicException(); using (SafeCertContextHandle hCertContext = originatorCert.CreateCertContextHandle()) { CERT_CONTEXT* pOriginatorCertContext = hCertContext.DangerousGetCertContext(); decryptPara.OriginatorPublicKey = pOriginatorCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey; // Do not factor this call out of the switch statement as leaving this "using" block will free up // native memory that decryptPara points to. return TryExecuteDecryptAgree(ref decryptPara); } } } case CMsgKeyAgreeOriginatorChoice.CMSG_KEY_AGREE_ORIGINATOR_PUBLIC_KEY: { decryptPara.OriginatorPublicKey = pKeyAgreeRecipientInfo->OriginatorPublicKeyInfo.PublicKey; return TryExecuteDecryptAgree(ref decryptPara); } default: return new CryptographicException(SR.Format(SR.Cryptography_Cms_Invalid_Originator_Identifier_Choice, originatorChoice)); } }); } }
private Exception TryDecryptTrans(KeyTransRecipientInfo recipientInfo, SafeProvOrNCryptKeyHandle hKey, CryptKeySpec keySpec) { KeyTransRecipientInfoPalWindows pal = (KeyTransRecipientInfoPalWindows)(recipientInfo.Pal); CMSG_CTRL_DECRYPT_PARA decryptPara; decryptPara.cbSize = Marshal.SizeOf<CMSG_CTRL_DECRYPT_PARA>(); decryptPara.hKey = hKey; decryptPara.dwKeySpec = keySpec; decryptPara.dwRecipientIndex = pal.Index; bool success = Interop.Crypt32.CryptMsgControl(_hCryptMsg, 0, MsgControlType.CMSG_CTRL_DECRYPT, ref decryptPara); if (!success) return Marshal.GetHRForLastWin32Error().ToCryptographicException(); return null; }
internal static extern bool CryptAcquireCertificatePrivateKey(SafeCertContextHandle pCert, CryptAcquireCertificatePrivateKeyFlags dwFlags, IntPtr pvParameters, out IntPtr phCryptProvOrNCryptKey, out CryptKeySpec pdwKeySpec, out bool pfCallerFreeProvOrNCryptKey);