From: Benoît Legat <benoit.legat@gmail.com> It can be either PROV_RSA_FULL or the newer PROV_RSA_AES or PROV_RSA_SCHANNEL but the current code was just always returning the legacy PROV_RSA_FULL. --- dlls/rsaenh/rsaenh.c | 6 ++++- dlls/rsaenh/tests/rsaenh.c | 53 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c index 4de6a2d0617..bb2657896f3 100644 --- a/dlls/rsaenh/rsaenh.c +++ b/dlls/rsaenh/rsaenh.c @@ -4176,7 +4176,11 @@ BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, strlen(pKeyContainer->szProvName)+1); case PP_PROVTYPE: - dwTemp = PROV_RSA_FULL; + switch (pKeyContainer->dwPersonality) { + case RSAENH_PERSONALITY_SCHANNEL: dwTemp = PROV_RSA_SCHANNEL; break; + case RSAENH_PERSONALITY_AES: dwTemp = PROV_RSA_AES; break; + default: dwTemp = PROV_RSA_FULL; break; + } return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp)); case PP_KEYSPEC: diff --git a/dlls/rsaenh/tests/rsaenh.c b/dlls/rsaenh/tests/rsaenh.c index d524b94d9f1..8e0db3b8d9b 100644 --- a/dlls/rsaenh/tests/rsaenh.c +++ b/dlls/rsaenh/tests/rsaenh.c @@ -4231,6 +4231,58 @@ static void test_pubexp(void) CryptReleaseContext(hprov, 0); } +static void test_pp_provtype(void) +{ + /* PP_PROVTYPE must return the provider type the caller opened the + * provider with — not always PROV_RSA_FULL. This matters because + * PFXImportCertStore reads PP_PROVTYPE and writes it into the + * cert's CRYPT_KEY_PROV_INFO.dwProvType; a later + * CryptAcquireContext using that value must find the same + * container. */ + static const struct + { + const char *prov_name; + DWORD prov_type; + } providers[] = + { + { MS_DEF_PROV_A, PROV_RSA_FULL }, + { MS_ENHANCED_PROV_A, PROV_RSA_FULL }, + { MS_STRONG_PROV_A, PROV_RSA_FULL }, + { MS_ENH_RSA_AES_PROV_A, PROV_RSA_AES }, + { MS_DEF_RSA_SCHANNEL_PROV_A, PROV_RSA_SCHANNEL }, + }; + DWORD i; + + for (i = 0; i < ARRAY_SIZE(providers); i++) + { + HCRYPTPROV hprov; + DWORD got, len = sizeof(got); + BOOL ret; + + ret = CryptAcquireContextA(&hprov, NULL, providers[i].prov_name, + providers[i].prov_type, CRYPT_VERIFYCONTEXT); + if (!ret) + { + /* Some providers may not be available on every Windows SKU; skip. */ + skip("CryptAcquireContextA(%s) failed: %#lx\n", + providers[i].prov_name, GetLastError()); + continue; + } + + got = 0; + ret = CryptGetProvParam(hprov, PP_PROVTYPE, (BYTE *)&got, &len, 0); + ok(ret, "%s: CryptGetProvParam(PP_PROVTYPE) failed: %#lx\n", + providers[i].prov_name, GetLastError()); + ok(len == sizeof(got), "%s: wrong PP_PROVTYPE size %lu\n", + providers[i].prov_name, len); + ok(got == providers[i].prov_type, + "%s: PP_PROVTYPE = %lu, expected %lu\n", + providers[i].prov_name, got, providers[i].prov_type); + + CryptReleaseContext(hprov, 0); + } +} + START_TEST(rsaenh) { test_RC4_salt(); @@ -4284,5 +4336,6 @@ START_TEST(rsaenh) test_key_derivation("AES"); test_rc2_import(); test_pubexp(); + test_pp_provtype(); clean_up_aes_environment(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11213