Hi, We have found few bugs in the MS Enhanced CSP implementation in wine (rsaenh.dll) and you'll find attached a patch that corrects them. Here is a description of the problems we found: - 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.
In order to support the PP_KEYSTORAGE parameter, we added three defined to wincrypt.h.
Cheers, Mounir IDRASSI IDRIX - Cryptography and IT Security Experts http://www.idrix.fr
From a7240539a2e3c83291c7cf206d55f1e4e7e75803 Mon Sep 17 00:00:00 2001
From: Mounir IDRASSI mounir.idrassi@idrix.fr Date: Sat, 5 May 2007 19:01:57 +0200 Subject: rsaenh: fix bugs in RSAENH_CPAcquireContext and RSAENH_CPGetProvParam
--- dlls/rsaenh/rsaenh.c | 32 +++++++++++++++++++++++++++++++- include/wincrypt.h | 5 +++++ 2 files changed, 36 insertions(+), 1 deletions(-)
diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c index 2ace2d5..9f55760 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);
@@ -2915,6 +2922,29 @@ BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, dwTemp = CRYPT_IMPL_SOFTWARE; return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
+ 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_VERSION: dwTemp = 0x00000200; return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp)); diff --git a/include/wincrypt.h b/include/wincrypt.h index 2219bd5..c897e96 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