From 62838182d55be0c454fe29a51aa172521d80bf2a Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Mon, 22 Oct 2018 14:17:59 +0300 Subject: [PATCH] crypt32: Add support for importing public key information to a 3rd party CSP. Based on a patch by Alexander Morozov. Signed-off-by: Dmitry Timoshkov Signed-off-by: Alexandre Julliard --- dlls/crypt32/encode.c | 35 +++++++++++++++++++++++++++++++---- include/wincrypt.h | 1 + 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c index 9a9850d6838..9d052b61c18 100644 --- a/dlls/crypt32/encode.c +++ b/dlls/crypt32/encode.c @@ -4974,21 +4974,48 @@ BOOL WINAPI CryptImportPublicKeyInfo(HCRYPTPROV hCryptProv, 0, 0, NULL, phKey); } -static BOOL WINAPI CRYPT_ImportRsaPublicKeyInfoEx(HCRYPTPROV hCryptProv, +typedef BOOL (WINAPI *ConvertPublicKeyInfoFunc)(DWORD dwCertEncodingType, + PCERT_PUBLIC_KEY_INFO pInfo, ALG_ID aiKeyAlg, DWORD dwFlags, + BYTE **ppbData, DWORD *dwDataLen); + +static BOOL WINAPI CRYPT_ImportPublicKeyInfoEx(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, ALG_ID aiKeyAlg, DWORD dwFlags, void *pvAuxInfo, HCRYPTKEY *phKey) { + static HCRYPTOIDFUNCSET set = NULL; + ConvertPublicKeyInfoFunc convertFunc = NULL; + HCRYPTOIDFUNCADDR hFunc = NULL; BOOL ret; - DWORD pubKeySize = 0; + DWORD pubKeySize; + LPBYTE pubKey; TRACE_(crypt)("(%08lx, %08x, %p, %08x, %08x, %p, %p)\n", hCryptProv, dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, pvAuxInfo, phKey); + if (!set) + set = CryptInitOIDFunctionSet(CRYPT_OID_CONVERT_PUBLIC_KEY_INFO_FUNC, 0); + CryptGetOIDFunctionAddress(set, dwCertEncodingType, pInfo->Algorithm.pszObjId, + 0, (void **)&convertFunc, &hFunc); + if (convertFunc) + { + pubKey = NULL; + pubKeySize = 0; + ret = convertFunc(dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, &pubKey, &pubKeySize); + if (ret) + { + ret = CryptImportKey(hCryptProv, pubKey, pubKeySize, 0, 0, phKey); + CryptMemFree(pubKey); + } + + CryptFreeOIDFunctionAddress(hFunc, 0); + return ret; + } + ret = CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB, pInfo->PublicKey.pbData, pInfo->PublicKey.cbData, 0, NULL, &pubKeySize); if (ret) { - LPBYTE pubKey = CryptMemAlloc(pubKeySize); + pubKey = CryptMemAlloc(pubKeySize); if (pubKey) { @@ -5031,7 +5058,7 @@ BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv, CryptGetOIDFunctionAddress(set, dwCertEncodingType, pInfo->Algorithm.pszObjId, 0, (void **)&importFunc, &hFunc); if (!importFunc) - importFunc = CRYPT_ImportRsaPublicKeyInfoEx; + importFunc = CRYPT_ImportPublicKeyInfoEx; ret = importFunc(hCryptProv, dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, pvAuxInfo, phKey); if (hFunc) diff --git a/include/wincrypt.h b/include/wincrypt.h index 0ba3b5ef796..bcb67ff0910 100644 --- a/include/wincrypt.h +++ b/include/wincrypt.h @@ -2345,6 +2345,7 @@ static const WCHAR CERT_TRUST_PUB_AUTHENTICODE_FLAGS_VALUE_NAME[] = #define CRYPT_OID_IMPORT_PRIVATE_KEY_INFO_FUNC "CryptDllImportPrivateKeyInfoEx" #define CRYPT_OID_VERIFY_CERTIFICATE_CHAIN_POLICY_FUNC \ "CertDllVerifyCertificateChainPolicy" +#define CRYPT_OID_CONVERT_PUBLIC_KEY_INFO_FUNC "CryptDllConvertPublicKeyInfo" #define URL_OID_GET_OBJECT_URL_FUNC "UrlDllGetObjectUrl" #define TIME_VALID_OID_GET_OBJECT_FUNC "TimeValidDllGetObject" #define CMSG_OID_GEN_CONTENT_ENCRYPT_KEY_FUNC "CryptMsgDllGenContentEncryptKey"