diff --git a/dll/win32/crypt32/cert.c b/dll/win32/crypt32/cert.c index 0088f006d3d..0065ba69d48 100644 --- a/dll/win32/crypt32/cert.c +++ b/dll/win32/crypt32/cert.c @@ -28,6 +28,7 @@ #include "wine/winternl.h" #define CRYPT_OID_INFO_HAS_EXTRA_FIELDS #include "wincrypt.h" +#include "snmp.h" #include "bcrypt.h" #include "winnls.h" #include "rpc.h" @@ -532,14 +533,19 @@ void CRYPT_FixKeyProvInfoPointers(PCRYPT_KEY_PROV_INFO info) provNameLen = (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR); data += provNameLen; - info->rgProvParam = (PCRYPT_KEY_PROV_PARAM)data; - data += info->cProvParam * sizeof(CRYPT_KEY_PROV_PARAM); - - for (i = 0; i < info->cProvParam; i++) + if (info->cProvParam) { - info->rgProvParam[i].pbData = data; - data += info->rgProvParam[i].cbData; + info->rgProvParam = (PCRYPT_KEY_PROV_PARAM)data; + data += info->cProvParam * sizeof(CRYPT_KEY_PROV_PARAM); + + for (i = 0; i < info->cProvParam; i++) + { + info->rgProvParam[i].pbData = data; + data += info->rgProvParam[i].cbData; + } } + else + info->rgProvParam = NULL; } BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, @@ -1242,6 +1248,12 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2); + /* RSA public key data should start with ASN_SEQUENCE, + * otherwise it's not a RSA_CSP_PUBLICKEYBLOB. + */ + if (!pPublicKey1->PublicKey.cbData || pPublicKey1->PublicKey.pbData[0] != ASN_SEQUENCE) + dwCertEncodingType = 0; + switch (GET_CERT_ENCODING_TYPE(dwCertEncodingType)) { case 0: /* Seems to mean "raw binary bits" */ @@ -1267,32 +1279,21 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, ret = FALSE; if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB, pPublicKey1->PublicKey.pbData, pPublicKey1->PublicKey.cbData, - 0, NULL, &length)) + CRYPT_DECODE_ALLOC_FLAG, &pblob1, &length)) { - pblob1 = CryptMemAlloc(length); if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB, - pPublicKey1->PublicKey.pbData, pPublicKey1->PublicKey.cbData, - 0, pblob1, &length)) + pPublicKey2->PublicKey.pbData, pPublicKey2->PublicKey.cbData, + CRYPT_DECODE_ALLOC_FLAG, &pblob2, &length)) { - if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB, - pPublicKey2->PublicKey.pbData, pPublicKey2->PublicKey.cbData, - 0, NULL, &length)) - { - pblob2 = CryptMemAlloc(length); - if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB, - pPublicKey2->PublicKey.pbData, pPublicKey2->PublicKey.cbData, - 0, pblob2, &length)) - { - /* The RSAPUBKEY structure directly follows the BLOBHEADER */ - RSAPUBKEY *pk1 = (LPVOID)(pblob1 + 1), - *pk2 = (LPVOID)(pblob2 + 1); - ret = (pk1->bitlen == pk2->bitlen) && (pk1->pubexp == pk2->pubexp) - && !memcmp(pk1 + 1, pk2 + 1, pk1->bitlen/8); - } - CryptMemFree(pblob2); - } + /* The RSAPUBKEY structure directly follows the BLOBHEADER */ + RSAPUBKEY *pk1 = (LPVOID)(pblob1 + 1), + *pk2 = (LPVOID)(pblob2 + 1); + ret = (pk1->bitlen == pk2->bitlen) && (pk1->pubexp == pk2->pubexp) + && !memcmp(pk1 + 1, pk2 + 1, pk1->bitlen/8); + + LocalFree(pblob2); } - CryptMemFree(pblob1); + LocalFree(pblob1); } break; @@ -1321,9 +1322,30 @@ DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType, } else { + PCCRYPT_OID_INFO info; DWORD size; PBYTE buf; - BOOL ret = CryptDecodeObjectEx(dwCertEncodingType, + BOOL ret; + + info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, pPublicKey->Algorithm.pszObjId, 0); + if (info) + { + HCRYPTKEY key; + + TRACE("public key algid %#x (%s)\n", info->u.Algid, debugstr_a(pPublicKey->Algorithm.pszObjId)); + + ret = CryptImportPublicKeyInfo(I_CryptGetDefaultCryptProv(info->u.Algid), dwCertEncodingType, pPublicKey, &key); + if (ret) + { + size = sizeof(len); + ret = CryptGetKeyParam(key, KP_KEYLEN, (BYTE *)&len, &size, 0); + CryptDestroyKey(key); + return len; + } + /* fallback to RSA */ + } + + ret = CryptDecodeObjectEx(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB, pPublicKey->PublicKey.pbData, pPublicKey->PublicKey.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); @@ -1794,7 +1816,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, } if (find) - ret = find(hCertStore, dwFlags, dwType, pvPara, pPrevCertContext); + ret = find(hCertStore, dwType, dwFlags, pvPara, pPrevCertContext); else if (compare) ret = cert_compare_certs_in_store(hCertStore, pPrevCertContext, compare, dwType, dwFlags, pvPara); @@ -2173,7 +2195,7 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash); if (!hCryptProv) - hCryptProv = CRYPT_GetDefaultProvider(); + hCryptProv = I_CryptGetDefaultCryptProv(0); if (!Algid) Algid = CALG_SHA1; if (ret) @@ -2202,7 +2224,7 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, dwCertEncodingType, pInfo, pbComputedHash, pcbComputedHash); if (!hCryptProv) - hCryptProv = CRYPT_GetDefaultProvider(); + hCryptProv = I_CryptGetDefaultCryptProv(0); if (!Algid) Algid = CALG_MD5; if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING) @@ -2254,7 +2276,7 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv, HCRYPTHASH hHash; if (!hCryptProv) - hCryptProv = CRYPT_GetDefaultProvider(); + hCryptProv = I_CryptGetDefaultCryptProv(0); oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, info->SignatureAlgorithm.pszObjId, 0); if (!oidInfo) @@ -2303,7 +2325,7 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, if (info->dwGroupId == CRYPT_HASH_ALG_OID_GROUP_ID) { if (!hCryptProv) - hCryptProv = CRYPT_GetDefaultProvider(); + hCryptProv = I_CryptGetDefaultCryptProv(0); ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash); if (ret) { @@ -2427,7 +2449,7 @@ static BOOL CRYPT_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEnco pubKeyID = hashID; /* Load the default provider if necessary */ if (!hCryptProv) - hCryptProv = CRYPT_GetDefaultProvider(); + hCryptProv = I_CryptGetDefaultCryptProv(0); ret = CryptImportPublicKeyInfoEx(hCryptProv, dwCertEncodingType, pubKeyInfo, pubKeyID, 0, NULL, &key); if (ret) @@ -3685,3 +3707,11 @@ const void * WINAPI CertCreateContext(DWORD dwContextType, DWORD dwEncodingType, return NULL; } } + +BOOL WINAPI CryptSetKeyIdentifierProperty(const CRYPT_HASH_BLOB *pKeyIdentifier, DWORD dwPropId, + DWORD dwFlags, LPCWSTR pwszComputerName, void *pvReserved, const void *pvData) +{ + FIXME("(%p, 0x%x, 0x%x, %s, %p, %p): stub\n", pKeyIdentifier, dwPropId, dwFlags, + debugstr_w(pwszComputerName), pvReserved, pvData); + return FALSE; +} diff --git a/dll/win32/crypt32/crypt32.spec b/dll/win32/crypt32/crypt32.spec index 0bc78a158d0..fc32570b52e 100644 --- a/dll/win32/crypt32/crypt32.spec +++ b/dll/win32/crypt32/crypt32.spec @@ -180,6 +180,7 @@ @ stdcall CryptSIPRetrieveSubjectGuidForCatalogFile(wstr long ptr) @ stdcall CryptSIPVerifyIndirectData(ptr ptr) @ stub CryptSetAsyncParam +@ stdcall CryptSetKeyIdentifierProperty(ptr long long wstr ptr ptr) @ stdcall CryptSetOIDFunctionValue(long str str wstr long ptr long) @ stub CryptSetProviderU @ stdcall CryptSignAndEncodeCertificate(long long long str ptr ptr ptr ptr ptr) @@ -194,7 +195,7 @@ @ stdcall CryptUnprotectMemory(ptr long long) @ stdcall CryptUnregisterDefaultOIDFunction(long str wstr) @ stdcall CryptUnregisterOIDFunction(long str str) -@ stub CryptUnregisterOIDInfo +@ stdcall CryptUnregisterOIDInfo(ptr) @ stdcall CryptVerifyCertificateSignature(long long ptr long ptr) @ stdcall CryptVerifyCertificateSignatureEx(long long long ptr long ptr long ptr) @ stdcall CryptVerifyDetachedMessageHash(ptr ptr long long ptr ptr ptr ptr) diff --git a/dll/win32/crypt32/crypt32_private.h b/dll/win32/crypt32/crypt32_private.h index e58db989b71..ac70fe04f82 100644 --- a/dll/win32/crypt32/crypt32_private.h +++ b/dll/win32/crypt32/crypt32_private.h @@ -116,6 +116,7 @@ typedef struct _CRYPT_SIGNED_INFO CRYPT_CONTENT_INFO content; DWORD cSignerInfo; PCMSG_CMS_SIGNER_INFO rgSignerInfo; + PDWORD signerKeySpec; } CRYPT_SIGNED_INFO; BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *, void *pvData, @@ -149,7 +150,7 @@ BOOL WINAPI CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType, /* Returns a handle to the default crypto provider; loads it if necessary. * Returns NULL on failure. */ -HCRYPTPROV CRYPT_GetDefaultProvider(void) DECLSPEC_HIDDEN; +HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(ALG_ID); HINSTANCE hInstance DECLSPEC_HIDDEN; diff --git a/dll/win32/crypt32/decode.c b/dll/win32/crypt32/decode.c index f77393eced1..6f51632dce1 100644 --- a/dll/win32/crypt32/decode.c +++ b/dll/win32/crypt32/decode.c @@ -215,7 +215,7 @@ static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags, if (pDecodePara && pDecodePara->pfnAlloc) *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded); else - *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded); + *(BYTE **)pvStructInfo = LocalAlloc(LPTR, bytesNeeded); if (!*(BYTE **)pvStructInfo) ret = FALSE; else @@ -1550,7 +1550,7 @@ static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded, case ASN_UTF8STRING: valueType = CERT_RDN_UTF8_STRING; bytesNeeded += MultiByteToWideChar(CP_UTF8, 0, - (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2; + (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * sizeof(WCHAR); break; default: SetLastError(CRYPT_E_ASN1_BADTAG); @@ -6279,48 +6279,8 @@ BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo) { - BOOL ret = FALSE; - CryptDecodeObjectFunc pCryptDecodeObject = NULL; - CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL; - HCRYPTOIDFUNCADDR hFunc = NULL; - - TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType, - debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags, - pvStructInfo, pcbStructInfo); - - if (!pvStructInfo && !pcbStructInfo) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - if (cbEncoded > MAX_ENCODED_LEN) - { - SetLastError(CRYPT_E_ASN1_LARGE); - return FALSE; - } - - if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType, - lpszStructType))) - { - TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n", - debugstr_a(lpszStructType)); - pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType, - lpszStructType, &hFunc); - if (!pCryptDecodeObject) - pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType, - lpszStructType, &hFunc); - } - if (pCryptDecodeObject) - ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType, - pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo); - else if (pCryptDecodeObjectEx) - ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType, - pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, - pvStructInfo, pcbStructInfo); - if (hFunc) - CryptFreeOIDFunctionAddress(hFunc, 0); - TRACE_(crypt)("returning %d\n", ret); - return ret; + return CryptDecodeObjectEx(dwCertEncodingType, lpszStructType, + pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo); } BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, diff --git a/dll/win32/crypt32/encode.c b/dll/win32/crypt32/encode.c index 62d2bc91f77..9d052b61c18 100644 --- a/dll/win32/crypt32/encode.c +++ b/dll/win32/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) @@ -4902,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) { @@ -4959,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/dll/win32/crypt32/main.c b/dll/win32/crypt32/main.c index 79a0ce1fd38..d0643f41077 100644 --- a/dll/win32/crypt32/main.c +++ b/dll/win32/crypt32/main.c @@ -35,6 +35,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt); static HCRYPTPROV hDefProv; HINSTANCE hInstance; +static CRITICAL_SECTION prov_param_cs; +static CRITICAL_SECTION_DEBUG prov_param_cs_debug = +{ + 0, 0, &prov_param_cs, + { &prov_param_cs_debug.ProcessLocksList, + &prov_param_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": prov_param_cs") } +}; +static CRITICAL_SECTION prov_param_cs = { &prov_param_cs_debug, -1, 0, 0, 0, 0 }; + BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved) { switch (fdwReason) @@ -56,7 +66,7 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved) return TRUE; } -HCRYPTPROV CRYPT_GetDefaultProvider(void) +static HCRYPTPROV CRYPT_GetDefaultProvider(void) { if (!hDefProv) { @@ -174,20 +184,69 @@ BOOL WINAPI I_CryptGetOssGlobal(DWORD x) return FALSE; } -HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(DWORD reserved) +static BOOL is_supported_algid(HCRYPTPROV prov, ALG_ID algid) { - HCRYPTPROV ret; + PROV_ENUMALGS prov_algs; + DWORD size = sizeof(prov_algs); + BOOL ret = FALSE; - TRACE("(%08x)\n", reserved); - - if (reserved) + /* This enumeration is not thread safe */ + EnterCriticalSection(&prov_param_cs); + if (CryptGetProvParam(prov, PP_ENUMALGS, (BYTE *)&prov_algs, &size, CRYPT_FIRST)) { + do + { + if (prov_algs.aiAlgid == algid) + { + ret = TRUE; + break; + } + } while (CryptGetProvParam(prov, PP_ENUMALGS, (BYTE *)&prov_algs, &size, CRYPT_NEXT)); + } + LeaveCriticalSection(&prov_param_cs); + return ret; +} + +HCRYPTPROV WINAPI DECLSPEC_HOTPATCH I_CryptGetDefaultCryptProv(ALG_ID algid) +{ + HCRYPTPROV prov, defprov; + + TRACE("(%08x)\n", algid); + + defprov = CRYPT_GetDefaultProvider(); + + if (algid && !is_supported_algid(defprov, algid)) + { + DWORD i = 0, type, size; + + while (CryptEnumProvidersW(i, NULL, 0, &type, NULL, &size)) + { + WCHAR *name = CryptMemAlloc(size); + if (name) + { + if (CryptEnumProvidersW(i, NULL, 0, &type, name, &size)) + { + if (CryptAcquireContextW(&prov, NULL, name, type, CRYPT_VERIFYCONTEXT)) + { + if (is_supported_algid(prov, algid)) + { + CryptMemFree(name); + return prov; + } + CryptReleaseContext(prov, 0); + } + } + CryptMemFree(name); + } + i++; + } + SetLastError(E_INVALIDARG); return 0; } - ret = CRYPT_GetDefaultProvider(); - CryptContextAddRef(ret, NULL, 0); - return ret; + + CryptContextAddRef(defprov, NULL, 0); + return defprov; } BOOL WINAPI I_CryptReadTrustedPublisherDWORDValueFromRegistry(LPCWSTR name, diff --git a/dll/win32/crypt32/msg.c b/dll/win32/crypt32/msg.c index 005fbf2c1f9..41323908557 100644 --- a/dll/win32/crypt32/msg.c +++ b/dll/win32/crypt32/msg.c @@ -567,7 +567,12 @@ static HCRYPTMSG CHashEncodeMsg_Open(DWORD dwFlags, const void *pvMsgEncodeInfo, prov = info->hCryptProv; else { - prov = CRYPT_GetDefaultProvider(); + prov = I_CryptGetDefaultCryptProv(algID); + if (!prov) + { + SetLastError(E_INVALIDARG); + return NULL; + } dwFlags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG; } msg = CryptMemAlloc(sizeof(CHashEncodeMsg)); @@ -921,17 +926,25 @@ typedef struct _CSignedMsgData * been constructed. */ static BOOL CSignedMsgData_ConstructSignerHandles(CSignedMsgData *msg_data, - DWORD signerIndex, HCRYPTPROV crypt_prov) + DWORD signerIndex, HCRYPTPROV *crypt_prov, DWORD *flags) { ALG_ID algID; BOOL ret; algID = CertOIDToAlgId( msg_data->info->rgSignerInfo[signerIndex].HashAlgorithm.pszObjId); - ret = CryptCreateHash(crypt_prov, algID, 0, 0, + + if (!*crypt_prov) + { + *crypt_prov = I_CryptGetDefaultCryptProv(algID); + if (!*crypt_prov) return FALSE; + *flags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG; + } + + ret = CryptCreateHash(*crypt_prov, algID, 0, 0, &msg_data->signerHandles->contentHash); if (ret && msg_data->info->rgSignerInfo[signerIndex].AuthAttrs.cAttr > 0) - ret = CryptCreateHash(crypt_prov, algID, 0, 0, + ret = CryptCreateHash(*crypt_prov, algID, 0, 0, &msg_data->signerHandles->authAttrHash); return ret; } @@ -1125,12 +1138,15 @@ static BOOL CSignedMsgData_Sign(CSignedMsgData *msg_data) for (i = 0; ret && i < msg_data->info->cSignerInfo; i++) { HCRYPTHASH hash; + DWORD keySpec = msg_data->info->signerKeySpec[i]; + if (!keySpec) + keySpec = AT_SIGNATURE; if (msg_data->info->rgSignerInfo[i].AuthAttrs.cAttr) hash = msg_data->signerHandles[i].authAttrHash; else hash = msg_data->signerHandles[i].contentHash; - ret = CryptSignHashW(hash, AT_SIGNATURE, NULL, 0, NULL, + ret = CryptSignHashW(hash, keySpec, NULL, 0, NULL, &msg_data->info->rgSignerInfo[i].EncryptedHash.cbData); if (ret) { @@ -1139,7 +1155,7 @@ static BOOL CSignedMsgData_Sign(CSignedMsgData *msg_data) msg_data->info->rgSignerInfo[i].EncryptedHash.cbData); if (msg_data->info->rgSignerInfo[i].EncryptedHash.pbData) { - ret = CryptSignHashW(hash, AT_SIGNATURE, NULL, 0, + ret = CryptSignHashW(hash, keySpec, NULL, 0, msg_data->info->rgSignerInfo[i].EncryptedHash.pbData, &msg_data->info->rgSignerInfo[i].EncryptedHash.cbData); if (ret) @@ -1189,6 +1205,7 @@ static void CSignedEncodeMsg_Close(HCRYPTMSG hCryptMsg) for (i = 0; i < msg->msg_data.info->cSignerInfo; i++) CSignerInfo_Free(&msg->msg_data.info->rgSignerInfo[i]); CSignedMsgData_CloseHandles(&msg->msg_data); + CryptMemFree(msg->msg_data.info->signerKeySpec); CryptMemFree(msg->msg_data.info->rgSignerInfo); CryptMemFree(msg->msg_data.info); } @@ -1411,6 +1428,9 @@ static HCRYPTMSG CSignedEncodeMsg_Open(DWORD dwFlags, msg->msg_data.info->cSignerInfo * sizeof(CMSG_CMS_SIGNER_INFO)); ret = CSignedMsgData_AllocateHandles(&msg->msg_data); + msg->msg_data.info->signerKeySpec = CryptMemAlloc(info->cSigners * sizeof(DWORD)); + if (!msg->msg_data.info->signerKeySpec) + ret = FALSE; for (i = 0; ret && i < msg->msg_data.info->cSignerInfo; i++) { if (info->rgSigners[i].SignerId.dwIdChoice == @@ -1422,11 +1442,13 @@ static HCRYPTMSG CSignedEncodeMsg_Open(DWORD dwFlags, if (ret) { ret = CSignedMsgData_ConstructSignerHandles( - &msg->msg_data, i, info->rgSigners[i].hCryptProv); + &msg->msg_data, i, &info->rgSigners[i].hCryptProv, &dwFlags); if (dwFlags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG) CryptReleaseContext(info->rgSigners[i].hCryptProv, 0); } + msg->msg_data.info->signerKeySpec[i] = + info->rgSigners[i].dwKeySpec; } } else @@ -1956,7 +1978,7 @@ static HCRYPTMSG CEnvelopedEncodeMsg_Open(DWORD dwFlags, prov = info->hCryptProv; else { - prov = CRYPT_GetDefaultProvider(); + prov = I_CryptGetDefaultCryptProv(0); dwFlags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG; } msg = CryptMemAlloc(sizeof(CEnvelopedEncodeMsg)); @@ -2078,7 +2100,7 @@ static void CDecodeMsg_Close(HCRYPTMSG hCryptMsg) { CDecodeMsg *msg = hCryptMsg; - if (msg->base.open_flags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG) + if (msg->crypt_prov && msg->base.open_flags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG) CryptReleaseContext(msg->crypt_prov, 0); switch (msg->type) { @@ -2329,6 +2351,14 @@ static BOOL CDecodeMsg_FinalizeHashedContent(CDecodeMsg *msg, &size); if (ret) algID = CertOIDToAlgId(hashAlgoID->pszObjId); + + if (!msg->crypt_prov) + { + msg->crypt_prov = I_CryptGetDefaultCryptProv(algID); + if (msg->crypt_prov) + msg->base.open_flags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG; + } + ret = CryptCreateHash(msg->crypt_prov, algID, 0, 0, &msg->u.hash); if (ret) { @@ -2375,7 +2405,7 @@ static BOOL CDecodeMsg_FinalizeSignedContent(CDecodeMsg *msg, ret = CSignedMsgData_AllocateHandles(&msg->u.signed_data); for (i = 0; ret && i < msg->u.signed_data.info->cSignerInfo; i++) ret = CSignedMsgData_ConstructSignerHandles(&msg->u.signed_data, i, - msg->crypt_prov); + &msg->crypt_prov, &msg->base.open_flags); if (ret) { CRYPT_DATA_BLOB *content; @@ -3541,13 +3571,7 @@ HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType, DWORD dwFlags, CDecodeMsg_Close, CDecodeMsg_GetParam, CDecodeMsg_Update, CDecodeMsg_Control); msg->type = dwMsgType; - if (hCryptProv) - msg->crypt_prov = hCryptProv; - else - { - msg->crypt_prov = CRYPT_GetDefaultProvider(); - msg->base.open_flags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG; - } + msg->crypt_prov = hCryptProv; memset(&msg->u, 0, sizeof(msg->u)); msg->msg_data.cbData = 0; msg->msg_data.pbData = NULL; diff --git a/dll/win32/crypt32/oid.c b/dll/win32/crypt32/oid.c index c9b0b412cf5..773264d3990 100644 --- a/dll/win32/crypt32/oid.c +++ b/dll/win32/crypt32/oid.c @@ -1,6 +1,7 @@ /* * Copyright 2002 Mike McCormack for CodeWeavers * Copyright 2005-2006 Juan Lang + * Copyright 2018 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,6 +23,9 @@ #include #include +#ifdef __REACTOS__ +#include +#endif #define NONAMELESSUNION #include "windef.h" #include "winbase.h" @@ -58,6 +62,7 @@ struct OIDFunctionSet struct OIDFunction { + HMODULE hModule; DWORD encoding; CRYPT_OID_FUNC_ENTRY entry; struct list next; @@ -72,6 +77,13 @@ static const WCHAR DISALLOWED[] = {'D','i','s','a','l','l','o','w','e','d',0}; static const LPCWSTR LocalizedKeys[] = {ROOT,MY,CA,ADDRESSBOOK,TRUSTEDPUBLISHER,DISALLOWED}; static WCHAR LocalizedNames[ARRAY_SIZE(LocalizedKeys)][256]; +static const WCHAR nameW[] = { 'N','a','m','e',0 }; +static const WCHAR algidW[] = { 'A','l','g','i','d',0 }; +static const WCHAR extraW[] = { 'E','x','t','r','a','I','n','f','o',0 }; +static const WCHAR cngalgidW[] = { 'C','N','G','A','l','g','i','d',0 }; +static const WCHAR cngextraalgidW[] = { 'C','N','G','E','x','t','r','a','A','l','g','i','d',0 }; +static const WCHAR flagsW[] = { 'F','l','a','g','s',0 }; + static void free_function_sets(void) { struct OIDFunctionSet *setCursor, *setNext; @@ -242,6 +254,8 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule, { struct OIDFunction *func; + TRACE("OID %s, func %p\n", debugstr_a(rgFuncEntry[i].pszOID), rgFuncEntry[i].pvFuncAddr); + if (!IS_INTOID(rgFuncEntry[i].pszOID)) func = CryptMemAlloc(sizeof(struct OIDFunction) + strlen(rgFuncEntry[i].pszOID) + 1); @@ -261,6 +275,7 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule, else func->entry.pszOID = rgFuncEntry[i].pszOID; func->entry.pvFuncAddr = rgFuncEntry[i].pvFuncAddr; + func->hModule = hModule; list_add_tail(&set->functions, &func->next); } else @@ -418,6 +433,38 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, return ret; } +static BOOL is_module_registered(HMODULE hModule) +{ + struct OIDFunctionSet *set; + BOOL ret = FALSE; + + EnterCriticalSection(&funcSetCS); + + LIST_FOR_EACH_ENTRY(set, &funcSets, struct OIDFunctionSet, next) + { + struct OIDFunction *function; + + EnterCriticalSection(&set->cs); + + LIST_FOR_EACH_ENTRY(function, &set->functions, struct OIDFunction, next) + { + if (function->hModule == hModule) + { + ret = TRUE; + break; + } + } + + LeaveCriticalSection(&set->cs); + + if (ret) break; + } + + LeaveCriticalSection(&funcSetCS); + + return ret; +} + BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, DWORD dwFlags) { @@ -431,9 +478,12 @@ BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, { struct FuncAddr *addr = hFuncAddr; - CryptMemFree(addr->dllList); - FreeLibrary(addr->lib); - CryptMemFree(addr); + if (!is_module_registered(addr->lib)) + { + CryptMemFree(addr->dllList); + FreeLibrary(addr->lib); + CryptMemFree(addr); + } } return TRUE; } @@ -652,14 +702,127 @@ error_close_key: return TRUE; } +/*********************************************************************** + * CryptUnregisterOIDInfo (CRYPT32.@) + */ +BOOL WINAPI CryptUnregisterOIDInfo(PCCRYPT_OID_INFO info) +{ + char *key_name; + HKEY root; + DWORD err; + + TRACE("(%p)\n", info); + + if (!info || info->cbSize != sizeof(*info) || !info->pszOID) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + + err = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptDllFindOIDInfo", 0, KEY_ALL_ACCESS, &root); + if (err != ERROR_SUCCESS) + { + SetLastError(err); + return FALSE; + } + + key_name = CryptMemAlloc(strlen(info->pszOID) + 16); + if (key_name) + { + sprintf(key_name, "%s!%u", info->pszOID, info->dwGroupId); + err = RegDeleteKeyA(root, key_name); + } + else + err = ERROR_OUTOFMEMORY; + + CryptMemFree(key_name); + RegCloseKey(root); + + if (err) + SetLastError(err); + + return !err; +} + /*********************************************************************** * CryptRegisterOIDInfo (CRYPT32.@) */ -BOOL WINAPI CryptRegisterOIDInfo(PCCRYPT_OID_INFO pInfo, DWORD dwFlags) +BOOL WINAPI CryptRegisterOIDInfo(PCCRYPT_OID_INFO info, DWORD flags) { - FIXME("(%p, %x): stub\n", pInfo, dwFlags ); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + char *key_name; + HKEY root = 0, key = 0; + DWORD err; + + TRACE("(%p, %x)\n", info, flags ); + + if (!info || info->cbSize != sizeof(*info) || !info->pszOID) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + + if (!info->dwGroupId) return TRUE; + + key_name = CryptMemAlloc(strlen(info->pszOID) + 16); + if (!key_name) + { + err = ERROR_OUTOFMEMORY; + goto done; + } + + err = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptDllFindOIDInfo", + 0, NULL, 0, KEY_ALL_ACCESS, NULL, &root, NULL); + if (err != ERROR_SUCCESS) goto done; + + sprintf(key_name, "%s!%u", info->pszOID, info->dwGroupId); + err = RegCreateKeyA(root, key_name, &key); + if (err != ERROR_SUCCESS) goto done; + + if (flags) + { + err = RegSetValueExW(key, flagsW, 0, REG_DWORD, (const BYTE *)&flags, sizeof(flags)); + if (err != ERROR_SUCCESS) goto done; + } + + if (info->pwszName) + { + err = RegSetValueExW(key, nameW, 0, REG_SZ, (const BYTE *)info->pwszName, (lstrlenW(info->pwszName) + 1) * sizeof(WCHAR)); + if (err != ERROR_SUCCESS) goto done; + } + + if (info->u.Algid) + { + err = RegSetValueExW(key, algidW, 0, REG_DWORD, (const BYTE *)&info->u.Algid, sizeof(info->u.Algid)); + if (err != ERROR_SUCCESS) goto done; + } + + if (info->ExtraInfo.cbData && info->ExtraInfo.pbData) + { + err = RegSetValueExW(key, extraW, 0, REG_BINARY, info->ExtraInfo.pbData, info->ExtraInfo.cbData); + if (err != ERROR_SUCCESS) goto done; + } + + if (info->pwszCNGAlgid) + { + err = RegSetValueExW(key, cngalgidW, 0, REG_SZ, (const BYTE *)info->pwszCNGAlgid, (lstrlenW(info->pwszCNGAlgid) + 1) * sizeof(WCHAR)); + if (err != ERROR_SUCCESS) goto done; + } + + if (info->pwszCNGExtraAlgid) + { + err = RegSetValueExW(key, cngextraalgidW, 0, REG_SZ, (const BYTE *)info->pwszCNGExtraAlgid, (lstrlenW(info->pwszCNGExtraAlgid) + 1) * sizeof(WCHAR)); + if (err != ERROR_SUCCESS) goto done; + } + +done: + CryptMemFree(key_name); + if (key) RegCloseKey(key); + if (root) RegCloseKey(root); + + if (err) + SetLastError(err); + + return !err; } /*********************************************************************** @@ -1405,6 +1568,125 @@ struct OIDInfo { struct list entry; }; +static struct OIDInfo *read_oid_info(HKEY root, char *key_name, DWORD *flags) +{ + HKEY key; + DWORD len, oid_len, name_len = 0, extra_len = 0, cngalgid_len = 0, cngextra_len = 0, group_id = 0; + struct OIDInfo *info; + char *p; + + if (RegOpenKeyExA(root, key_name, 0, KEY_READ, &key)) + return NULL; + + p = strchr(key_name, '!'); + if (p) + { + group_id = strtol(p + 1, NULL, 10); + *p = 0; + } + + oid_len = strlen(key_name) + 1; + + RegQueryValueExW(key, nameW, NULL, NULL, NULL, &name_len); + RegQueryValueExW(key, extraW, NULL, NULL, NULL, &extra_len); + RegQueryValueExW(key, cngalgidW, NULL, NULL, NULL, &cngalgid_len); + RegQueryValueExW(key, cngextraalgidW, NULL, NULL, NULL, &cngextra_len); + + info = CryptMemAlloc(sizeof(*info) + oid_len + name_len + extra_len + cngalgid_len + cngextra_len); + if (info) + { + *flags = 0; + len = sizeof(*flags); + RegQueryValueExW(key, flagsW, NULL, NULL, (BYTE *)flags, &len); + + memset(info, 0, sizeof(*info)); + info->info.cbSize = sizeof(info->info); + + p = (char *)(info + 1); + + info->info.pszOID = p; + strcpy((char *)info->info.pszOID, key_name); + p += oid_len; + + if (name_len) + { + info->info.pwszName = (WCHAR *)p; + RegQueryValueExW(key, nameW, NULL, NULL, (BYTE *)info->info.pwszName, &name_len); + p += name_len; + } + + info->info.dwGroupId = group_id; + + len = sizeof(info->info.u.Algid); + RegQueryValueExW(key, algidW, NULL, NULL, (BYTE *)&info->info.u.Algid, &len); + + if (extra_len) + { + info->info.ExtraInfo.cbData = extra_len; + info->info.ExtraInfo.pbData = (BYTE *)p; + RegQueryValueExW(key, extraW, NULL, NULL, info->info.ExtraInfo.pbData, &extra_len); + p += extra_len; + } + + if (cngalgid_len) + { + info->info.pwszCNGAlgid = (WCHAR *)p; + RegQueryValueExW(key, cngalgidW, NULL, NULL, (BYTE *)info->info.pwszCNGAlgid, &cngalgid_len); + p += cngalgid_len; + } + + if (cngextra_len) + { + info->info.pwszCNGExtraAlgid = (WCHAR *)p; + RegQueryValueExW(key, cngextraalgidW, NULL, NULL, (BYTE *)info->info.pwszCNGExtraAlgid, &cngalgid_len); + } + } + + RegCloseKey(key); + + return info; +} + +static void init_registered_oid_info(void) +{ + DWORD err, idx; + HKEY root; + + err = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptDllFindOIDInfo", + 0, KEY_ALL_ACCESS, &root); + if (err != ERROR_SUCCESS) return; + + idx = 0; + for (;;) + { + char key_name[MAX_PATH]; + struct OIDInfo *info; + DWORD flags; + + err = RegEnumKeyA(root, idx++, key_name, MAX_PATH); + if (err == ERROR_NO_MORE_ITEMS) + break; + + if (err == ERROR_SUCCESS) + { + if ((info = read_oid_info(root, key_name, &flags))) + { + TRACE("adding oid %s, name %s, groupid %u, algid %u, extra %u, CNG algid %s, CNG extra %s\n", + debugstr_a(info->info.pszOID), debugstr_w(info->info.pwszName), + info->info.dwGroupId, info->info.u.Algid, info->info.ExtraInfo.cbData, + debugstr_w(info->info.pwszCNGAlgid), debugstr_w(info->info.pwszCNGExtraAlgid)); + + if (flags & CRYPT_INSTALL_OID_INFO_BEFORE_FLAG) + list_add_head(&oidInfo, &info->entry); + else + list_add_tail(&oidInfo, &info->entry); + } + } + } + + RegCloseKey(root); +} + static void init_oid_info(void) { DWORD i; @@ -1632,6 +1914,7 @@ DWORD WINAPI CertOIDToAlgId(LPCSTR pszObjId) void crypt_oid_init(void) { init_oid_info(); + init_registered_oid_info(); } void crypt_oid_free(void) diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 532d520a7ef..cdf4cda9c62 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -58,7 +58,7 @@ reactos/dll/win32/comctl32 # Synced to Wine-3.0 reactos/dll/win32/comdlg32 # Synced to WineStaging-4.0 reactos/dll/win32/compstui # Synced to WineStaging-3.3 reactos/dll/win32/credui # Synced to WineStaging-4.0 -reactos/dll/win32/crypt32 # Synced to WineStaging-3.17 +reactos/dll/win32/crypt32 # Synced to WineStaging-4.0 reactos/dll/win32/cryptdlg # Synced to WineStaging-3.3 reactos/dll/win32/cryptdll # Synced to WineStaging-3.3 reactos/dll/win32/cryptnet # Synced to WineStaging-3.3