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