rsaenh: fix bugs in RSAENH_CPAcquireContext and
RSAENH_CPGetProvParam
Mounir IDRASSI
mounir.idrassi at idrix.fr
Sun May 6 17:02:09 CDT 2007
Hi,
The attached patch corrects the following bugs in MS Enhanced CSP
implementation in wine and adds tests that illustrate them.
- In RSAENH_CPAcquireContext : when specifying CRYPT_DELETEKEYSET,
the function always deletes the container for the local user, while it
should check the CRYPT_MACHINE_KEYSET flag to see if it should be
deleted on the local machine or for the local user.
- In RSAENH_CPGetProvParam: The following mandatory parameters were
not supported : PP_UNIQUE_CONTAINER, PP_PROVTYPE, PP_KEYSPEC,
PP_KEYSET_TYPE, PP_KEYSTORAGE.
Mounir IDRASSI
IDRIX - Cryptography and IT Security Experts
http://www.idrix.fr
-------------- next part --------------
>From 33a9a1f1573299c9b83c2d699dd4ac31f097a682 Mon Sep 17 00:00:00 2001
From: Mounir IDRASSI <mounir.idrassi at idrix.fr>
Date: Sun, 6 May 2007 21:36:08 +0200
Subject: rsaenh: fix bugs in RSAENH_CPAcquireContext and RSAENH_CPGetProvParam
---
dlls/rsaenh/rsaenh.c | 32 ++++++++++++++++++++++-
dlls/rsaenh/tests/rsaenh.c | 61 ++++++++++++++++++++++++++++++++++++++++---
include/wincrypt.h | 5 +++
3 files changed, 92 insertions(+), 6 deletions(-)
diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c
index 2ace2d5..488b90c 100644
--- a/dlls/rsaenh/rsaenh.c
+++ b/dlls/rsaenh/rsaenh.c
@@ -1473,7 +1473,13 @@ BOOL WINAPI RSAENH_CPAcquireContext(HCRYPTPROV *phProv, LPSTR pszContainer,
SetLastError(NTE_BAD_KEYSET_PARAM);
return FALSE;
} else {
- if (!RegDeleteKeyA(HKEY_CURRENT_USER, szRegKey)) {
+ HKEY hRootKey;
+ if (dwFlags & CRYPT_MACHINE_KEYSET)
+ hRootKey = HKEY_LOCAL_MACHINE;
+ else
+ hRootKey = HKEY_CURRENT_USER;
+
+ if (!RegDeleteKeyA(hRootKey, szRegKey)) {
SetLastError(ERROR_SUCCESS);
return TRUE;
} else {
@@ -2899,6 +2905,7 @@ BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData,
switch (dwParam)
{
case PP_CONTAINER:
+ case PP_UNIQUE_CONTAINER:/* MSDN says we can return the same value as PP_CONTAINER */
return copy_param(pbData, pdwDataLen, (CONST BYTE*)pKeyContainer->szName,
strlen(pKeyContainer->szName)+1);
@@ -2906,6 +2913,29 @@ BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData,
return copy_param(pbData, pdwDataLen, (CONST BYTE*)pKeyContainer->szProvName,
strlen(pKeyContainer->szProvName)+1);
+ case PP_PROVTYPE:
+ dwTemp = PROV_RSA_FULL;
+ return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
+
+ case PP_KEYSPEC:
+ dwTemp = AT_SIGNATURE | AT_KEYEXCHANGE;
+ return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
+
+ case PP_KEYSET_TYPE:
+ dwTemp = pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET;
+ return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
+
+ case PP_KEYSTORAGE:
+ dwTemp = GetVersion();
+ /* for Windows NT, 95,98, Me, return CRYPT_PSTORE | CRYPT_UI_PROMPT | CRYPT_SEC_DESCR
+ * for the others, return CRYPT_SEC_DESCR
+ */
+ if(dwTemp < 0x80000000 && ((dwTemp & 0x000000FF) != 0x00000004))
+ dwTemp = CRYPT_SEC_DESCR;
+ else
+ dwTemp = CRYPT_PSTORE | CRYPT_UI_PROMPT | CRYPT_SEC_DESCR;
+ return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
+
case PP_SIG_KEYSIZE_INC:
case PP_KEYX_KEYSIZE_INC:
dwTemp = 8;
diff --git a/dlls/rsaenh/tests/rsaenh.c b/dlls/rsaenh/tests/rsaenh.c
index fe27f4b..dd7013b 100644
--- a/dlls/rsaenh/tests/rsaenh.c
+++ b/dlls/rsaenh/tests/rsaenh.c
@@ -1480,7 +1480,8 @@ static void test_null_provider(void)
HCRYPTPROV prov;
HCRYPTKEY key;
BOOL result;
- DWORD keySpec, dataLen;
+ DWORD keySpec, dataLen,dwParam;
+ char szName[MAX_PATH];
result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
@@ -1513,10 +1514,23 @@ static void test_null_provider(void)
CRYPT_VERIFYCONTEXT);
ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
if (!result) return;
+ /* Test provider parameters getter */
+ dataLen = sizeof(dwParam);
+ result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
+ ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
+ "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
+ dataLen = sizeof(dwParam);
+ result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
+ ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
+ "Expected 0, got 0x%08X\n",dwParam);
+ dataLen = sizeof(dwParam);
+ result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
+ ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
+ "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
+
dataLen = sizeof(keySpec);
result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
- if (result)
- ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
+ ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
"Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
/* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
* supported, you can't get the keys from this container.
@@ -1558,9 +1572,21 @@ static void test_null_provider(void)
if (!result) return;
dataLen = sizeof(keySpec);
result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
- if (result)
- ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
+ ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
"Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
+ /* PP_CONTAINER parameter */
+ dataLen = sizeof(szName);
+ result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
+ ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
+ "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
+ (result)? "TRUE":"FALSE",GetLastError(),dataLen);
+ /* PP_UNIQUE_CONTAINER parameter */
+ dataLen = sizeof(szName);
+ result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
+ ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
+ "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
+ (result)? "TRUE":"FALSE",GetLastError(),dataLen);
+
result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
ok(!result && GetLastError() == NTE_NO_KEY,
"Expected NTE_NO_KEY, got %08x\n", GetLastError());
@@ -1603,6 +1629,31 @@ static void test_null_provider(void)
CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
CRYPT_DELETEKEYSET);
+
+ /* test the machine key set */
+ CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
+ CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
+ result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
+ CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
+ ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
+ /* check PP_KEYSET_TYPE parameter */
+ dataLen = sizeof(dwParam);
+ result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
+ ok(result && dataLen == sizeof(dwParam) && dwParam == CRYPT_MACHINE_KEYSET,
+ "Expected CRYPT_MACHINE_KEYSET, got 0x%08X\n",dwParam);
+ CryptReleaseContext(prov, 0);
+ result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
+ CRYPT_MACHINE_KEYSET);
+ ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
+ CryptReleaseContext(prov,0);
+ result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
+ CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
+ ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
+ GetLastError());
+ result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
+ CRYPT_MACHINE_KEYSET);
+ ok(!result && GetLastError() == NTE_BAD_KEYSET ,
+ "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
}
START_TEST(rsaenh)
diff --git a/include/wincrypt.h b/include/wincrypt.h
index 2219bd5..2aaa89b 100644
--- a/include/wincrypt.h
+++ b/include/wincrypt.h
@@ -1613,6 +1613,11 @@ static const WCHAR MS_SCARD_PROV_W[] = { 'M','i','c','r','o','s','o','
#define PP_KEYSPEC 39
#define PP_ENUMEX_SIGNING_PROT 40
+/* Values returned by CryptGetProvParam of PP_KEYSTORAGE */
+#define CRYPT_SEC_DESCR 0x00000001
+#define CRYPT_PSTORE 0x00000002
+#define CRYPT_UI_PROMPT 0x00000004
+
/* Crypt{Get/Set}KeyParam */
#define KP_IV 1
#define KP_SALT 2
--
1.4.4.2
More information about the wine-patches
mailing list