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 | 48 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 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..26f05cd0855 100644 --- a/dlls/rsaenh/tests/rsaenh.c +++ b/dlls/rsaenh/tests/rsaenh.c @@ -4231,6 +4231,53 @@ 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. 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); + ok(ret, "%s: CryptAcquireContextA failed: %#lx\n", + providers[i].prov_name, GetLastError()); + if (!ret) 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 +4331,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