rsaenh: CPGetProvParam's PP_ENUMCONTAINERS
Michael Jung
mjung at iss.tu-darmstadt.de
Wed Feb 9 08:21:58 CST 2005
On Wednesday 09 February 2005 13:38, Alexandre Julliard wrote:
> The test fails for me:
>
> rsaenh.c:1383: Test failed: 00000103
> rsaenh.c:1391: Test failed: 0, 00000103
It doesn't fail for me on a clean .wine directory and a fresh wine cvs
install. I've attached a modified version of the patch with some added
tracing code. If you find a minute, could you please try it and send me a
'crypt' debug channel trace? Do not apply this patch to cvs, please.
Thanks,
--
Michael Jung
mjung at iss.tu-darmstadt.de
-------------- next part --------------
Index: dlls/rsaenh/rsaenh.c
===================================================================
RCS file: /home/wine/wine/dlls/rsaenh/rsaenh.c,v
retrieving revision 1.20
diff -u -r1.20 rsaenh.c
--- dlls/rsaenh/rsaenh.c 31 Jan 2005 11:28:41 -0000 1.20
+++ dlls/rsaenh/rsaenh.c 9 Feb 2005 14:13:24 -0000
@@ -119,6 +119,7 @@
DWORD dwFlags;
DWORD dwPersonality;
DWORD dwEnumAlgsCtr;
+ DWORD dwEnumContainersCtr;
CHAR szName[MAX_PATH];
CHAR szProvName[MAX_PATH];
HCRYPTKEY hKeyExchangeKeyPair;
@@ -977,6 +978,31 @@
pKeyContainer->dwPersonality = RSAENH_PERSONALITY_STRONG;
}
}
+
+ /* The new key container has to be inserted into the CSP immediately
+ * after creation to be available for CPGetProvParam's PP_ENUMCONTAINERS. */
+ if (!(dwFlags & CRYPT_VERIFYCONTEXT)) {
+ BYTE szRSABase[MAX_PATH];
+ HKEY hRootKey, hKey;
+ LONG lResult;
+
+ sprintf(szRSABase, RSAENH_REGKEY, pKeyContainer->szName);
+
+ if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET) {
+ hRootKey = HKEY_LOCAL_MACHINE;
+ } else {
+ hRootKey = HKEY_CURRENT_USER;
+ }
+
+ lResult = RegCreateKeyExA(hRootKey, szRSABase, 0, NULL,
+ REG_OPTION_NON_VOLATILE, 0, NULL, &hKey, NULL);
+ if (lResult == ERROR_SUCCESS) {
+ RegCloseKey(hKey);
+ } else {
+ WARN("Failed to create new key container registry key: "
+ "%08lx\n", lResult);
+ }
+ }
}
return hKeyContainer;
@@ -1862,10 +1888,10 @@
} else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_STREAM) {
encrypt_stream_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, *pdwDataLen);
} else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_RSA) {
- if (pCryptKey->aiAlgid == CALG_RSA_SIGN) {
- SetLastError(NTE_BAD_KEY);
- return FALSE;
- }
+ if (pCryptKey->aiAlgid == CALG_RSA_SIGN) {
+ SetLastError(NTE_BAD_KEY);
+ return FALSE;
+ }
if (dwBufLen < pCryptKey->dwBlockLen) {
SetLastError(ERROR_MORE_DATA);
return FALSE;
@@ -1982,10 +2008,10 @@
} else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_STREAM) {
encrypt_stream_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, *pdwDataLen);
} else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_RSA) {
- if (pCryptKey->aiAlgid == CALG_RSA_SIGN) {
- SetLastError(NTE_BAD_KEY);
- return FALSE;
- }
+ if (pCryptKey->aiAlgid == CALG_RSA_SIGN) {
+ SetLastError(NTE_BAD_KEY);
+ return FALSE;
+ }
encrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, pbData, RSAENH_DECRYPT);
if (!unpad_data(pbData, pCryptKey->dwBlockLen, pbData, pdwDataLen, dwFlags)) return FALSE;
Final = TRUE;
@@ -2717,6 +2743,9 @@
KEYCONTAINER *pKeyContainer;
PROV_ENUMALGS provEnumalgs;
DWORD dwTemp;
+ BYTE szRSABase[MAX_PATH];
+ HKEY hKey, hRootKey;
+ LONG lResult;
/* This is for dwParam 41, which does not seem to be documented
* on MSDN. IE6 SP1 asks for it in the 'About' dialog, however.
@@ -2763,7 +2792,53 @@
case PP_KEYX_KEYSIZE_INC:
dwTemp = 8;
return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
-
+
+ case PP_ENUMCONTAINERS:
+ if ((dwFlags & CRYPT_FIRST) == CRYPT_FIRST) pKeyContainer->dwEnumContainersCtr = 0;
+
+ if (!pbData) {
+ *pdwDataLen = (DWORD)MAX_PATH + 1;
+ return TRUE;
+ }
+
+ sprintf(szRSABase, RSAENH_REGKEY, "");
+
+ if (dwFlags & CRYPT_MACHINE_KEYSET) {
+ hRootKey = HKEY_LOCAL_MACHINE;
+ } else {
+ hRootKey = HKEY_CURRENT_USER;
+ }
+
+ lResult = RegOpenKeyExA(hRootKey, szRSABase, 0, KEY_READ, &hKey);
+ if (lResult != ERROR_SUCCESS)
+ {
+ WARN("Failed to open CSP registry key: %08lx\n", lResult);
+ SetLastError(ERROR_NO_MORE_ITEMS);
+ return FALSE;
+ }
+
+ dwTemp = *pdwDataLen;
+ lResult = RegEnumKeyExA(hKey, pKeyContainer->dwEnumContainersCtr, pbData, &dwTemp,
+ NULL, NULL, NULL, NULL);
+ switch (lResult)
+ {
+ case ERROR_MORE_DATA:
+ *pdwDataLen = (DWORD)MAX_PATH + 1;
+
+ case ERROR_SUCCESS:
+ pKeyContainer->dwEnumContainersCtr++;
+ RegCloseKey(hKey);
+ return TRUE;
+
+ default:
+ WARN("Error enumerating containers: %08lx\n", lResult);
+
+ case ERROR_NO_MORE_ITEMS:
+ SetLastError(ERROR_NO_MORE_ITEMS);
+ RegCloseKey(hKey);
+ return FALSE;
+ }
+
case PP_ENUMALGS:
case PP_ENUMALGS_EX:
if (((pKeyContainer->dwEnumAlgsCtr >= RSAENH_MAX_ENUMALGS-1) ||
Index: dlls/rsaenh/tests/rsaenh.c
===================================================================
RCS file: /home/wine/wine/dlls/rsaenh/tests/rsaenh.c,v
retrieving revision 1.7
diff -u -r1.7 rsaenh.c
--- dlls/rsaenh/tests/rsaenh.c 31 Jan 2005 11:28:41 -0000 1.7
+++ dlls/rsaenh/tests/rsaenh.c 9 Feb 2005 14:13:24 -0000
@@ -1366,6 +1366,31 @@
CryptReleaseContext(hProv, 0);
}
+void test_enum_container()
+{
+ BYTE abContainerName[256];
+ DWORD dwBufferLen;
+ BOOL result, fFound = FALSE;
+
+ /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
+ * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
+ result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
+ ok (result && dwBufferLen == MAX_PATH + 1, "%08lx\n", GetLastError());
+
+ /* If the result fits into abContainerName dwBufferLen is left untouched */
+ dwBufferLen = (DWORD)sizeof(abContainerName);
+ result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
+ ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08lx\n", GetLastError());
+
+ /* We only check, if the currently open 'winetest' container is among the enumerated. */
+ do {
+ if (!strcmp(abContainerName, "winetest")) fFound = TRUE;
+ dwBufferLen = (DWORD)sizeof(abContainerName);
+ } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
+
+ ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08lx\n", fFound, GetLastError());
+}
+
START_TEST(rsaenh)
{
if (!init_environment())
@@ -1384,6 +1409,7 @@
test_import_private();
test_verify_signature();
test_rsa_encrypt();
+ test_enum_container();
clean_up_environment();
test_schannel_provider();
}
More information about the wine-devel
mailing list