Dmitry Timoshkov : crypt32: Add support for exporting public key information from a 3rd party CSP.
Alexandre Julliard
julliard at winehq.org
Tue Oct 23 16:10:01 CDT 2018
Module: wine
Branch: master
Commit: f0d6637f0f71a605cfb8a49d2f45a2ce6a46beaf
URL: https://source.winehq.org/git/wine.git/?a=commit;h=f0d6637f0f71a605cfb8a49d2f45a2ce6a46beaf
Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date: Mon Oct 22 14:17:56 2018 +0300
crypt32: Add support for exporting public key information from a 3rd party CSP.
Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/crypt32/encode.c | 90 +++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 81 insertions(+), 9 deletions(-)
diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c
index 62d2bc9..9a9850d 100644
--- a/dlls/crypt32/encode.c
+++ b/dlls/crypt32/encode.c
@@ -4779,20 +4779,22 @@ BOOL WINAPI CryptExportPublicKeyInfo(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv,
NULL, 0, NULL, pInfo, pcbInfo);
}
-static BOOL WINAPI CRYPT_ExportRsaPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv,
+typedef BOOL (WINAPI *EncodePublicKeyAndParametersFunc)(DWORD dwCertEncodingType,
+ LPSTR pszPublicKeyObjId, BYTE *pbPubKey, DWORD cbPubKey, DWORD dwFlags, void *pvAuxInfo,
+ BYTE **ppPublicKey, DWORD *pcbPublicKey, BYTE **ppbParams, DWORD *pcbParams);
+
+static BOOL WINAPI CRYPT_ExportPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv,
DWORD dwKeySpec, DWORD dwCertEncodingType, LPSTR pszPublicKeyObjId,
DWORD dwFlags, void *pvAuxInfo, PCERT_PUBLIC_KEY_INFO pInfo, DWORD *pcbInfo)
{
BOOL ret;
HCRYPTKEY key;
- static CHAR oid[] = szOID_RSA_RSA;
+ static CHAR rsa_oid[] = szOID_RSA_RSA;
TRACE_(crypt)("(%08lx, %d, %08x, %s, %08x, %p, %p, %d)\n", hCryptProv,
dwKeySpec, dwCertEncodingType, debugstr_a(pszPublicKeyObjId), dwFlags,
pvAuxInfo, pInfo, pInfo ? *pcbInfo : 0);
- if (!pszPublicKeyObjId)
- pszPublicKeyObjId = oid;
if ((ret = CryptGetUserKey(hCryptProv, dwKeySpec, &key)))
{
DWORD keySize = 0;
@@ -4800,16 +4802,86 @@ static BOOL WINAPI CRYPT_ExportRsaPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDL
ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, NULL, &keySize);
if (ret)
{
- LPBYTE pubKey = CryptMemAlloc(keySize);
+ PUBLICKEYSTRUC *pubKey = CryptMemAlloc(keySize);
if (pubKey)
{
- ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, pubKey,
- &keySize);
+ ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, (BYTE *)pubKey, &keySize);
if (ret)
{
- DWORD encodedLen = 0;
+ DWORD encodedLen;
+
+ if (!pszPublicKeyObjId)
+ {
+ static HCRYPTOIDFUNCSET set;
+ EncodePublicKeyAndParametersFunc encodeFunc = NULL;
+ HCRYPTOIDFUNCADDR hFunc = NULL;
+
+ pszPublicKeyObjId = (LPSTR)CertAlgIdToOID(pubKey->aiKeyAlg);
+ TRACE("public key algid %#x (%s)\n", pubKey->aiKeyAlg, debugstr_a(pszPublicKeyObjId));
+
+ if (!set) /* FIXME: there is no a public macro */
+ set = CryptInitOIDFunctionSet("CryptDllEncodePublicKeyAndParameters", 0);
+
+ CryptGetOIDFunctionAddress(set, dwCertEncodingType, pszPublicKeyObjId, 0, (void **)&encodeFunc, &hFunc);
+ if (encodeFunc)
+ {
+ BYTE *key_data = NULL;
+ DWORD key_size = 0;
+ BYTE *params = NULL;
+ DWORD params_size = 0;
+
+ ret = encodeFunc(dwCertEncodingType, pszPublicKeyObjId, (BYTE *)pubKey, keySize,
+ dwFlags, pvAuxInfo, &key_data, &key_size, ¶ms, ¶ms_size);
+ if (ret)
+ {
+ DWORD oid_size = strlen(pszPublicKeyObjId) + 1;
+ DWORD size_needed = sizeof(*pInfo) + oid_size + key_size + params_size;
+
+ if (!pInfo)
+ *pcbInfo = size_needed;
+ else if (*pcbInfo < size_needed)
+ {
+ *pcbInfo = size_needed;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ *pcbInfo = size_needed;
+ pInfo->Algorithm.pszObjId = (char *)(pInfo + 1);
+ lstrcpyA(pInfo->Algorithm.pszObjId, pszPublicKeyObjId);
+ if (params)
+ {
+ pInfo->Algorithm.Parameters.cbData = params_size;
+ pInfo->Algorithm.Parameters.pbData = (BYTE *)pInfo->Algorithm.pszObjId + oid_size;
+ memcpy(pInfo->Algorithm.Parameters.pbData, params, params_size);
+ }
+ else
+ {
+ pInfo->Algorithm.Parameters.cbData = 0;
+ pInfo->Algorithm.Parameters.pbData = NULL;
+ }
+ pInfo->PublicKey.pbData = (BYTE *)pInfo->Algorithm.pszObjId + oid_size + params_size;
+ pInfo->PublicKey.cbData = key_size;
+ memcpy(pInfo->PublicKey.pbData, key_data, key_size);
+ pInfo->PublicKey.cUnusedBits = 0;
+ }
+
+ CryptMemFree(key_data);
+ CryptMemFree(params);
+ }
+
+ CryptMemFree(pubKey);
+ CryptFreeOIDFunctionAddress(hFunc, 0);
+ return ret;
+ }
+
+ /* fallback to RSA */
+ pszPublicKeyObjId = rsa_oid;
+ }
+ encodedLen = 0;
ret = CryptEncodeObject(dwCertEncodingType,
RSA_CSP_PUBLICKEYBLOB, pubKey, NULL, &encodedLen);
if (ret)
@@ -4887,7 +4959,7 @@ BOOL WINAPI CryptExportPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptPro
0, (void **)&exportFunc, &hFunc);
}
if (!exportFunc)
- exportFunc = CRYPT_ExportRsaPublicKeyInfoEx;
+ exportFunc = CRYPT_ExportPublicKeyInfoEx;
ret = exportFunc(hCryptProv, dwKeySpec, dwCertEncodingType,
pszPublicKeyObjId, dwFlags, pvAuxInfo, pInfo, pcbInfo);
if (hFunc)
More information about the wine-cvs
mailing list