[PATCH 4/4] crypt32: Add support for importing public key information to a 3rd party CSP.

Dmitry Timoshkov dmitry at baikal.ru
Mon Oct 22 06:17:59 CDT 2018


Based on a patch by Alexander Morozov.

Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 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 9a9850d683..9d052b61c1 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 0ba3b5ef79..bcb67ff091 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"
-- 
2.17.1




More information about the wine-devel mailing list