rsaenh: Don't reset the salt length after setting a salt for Base and Strong providers

Bruno Jesus 00cpxxx at gmail.com
Sat Jan 10 04:05:14 CST 2015


Fixes bug https://bugs.winehq.org/show_bug.cgi?id=23208

I have reduced and enforced the scope of broken so the tests still
work in NT4 (I tested manually). The way broken was used before was
the cause that this issue was not found until now so I think it's a
valid change.

More details: https://bugs.winehq.org/show_bug.cgi?id=23208#c35

Windows 8 gives 65 unrelated previous errors.
-------------- next part --------------
diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c
index 7123ffb..ebafa0e 100644
--- a/dlls/rsaenh/rsaenh.c
+++ b/dlls/rsaenh/rsaenh.c
@@ -3462,6 +3462,8 @@ BOOL WINAPI RSAENH_CPSetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam
             switch (pCryptKey->aiAlgid) {
                 case CALG_RC2:
                 case CALG_RC4:
+                {
+                    KEYCONTAINER *pKeyContainer = get_key_container(pCryptKey->hProv);
                     if (!pbData)
                     {
                         SetLastError(ERROR_INVALID_PARAMETER);
@@ -3474,11 +3476,13 @@ BOOL WINAPI RSAENH_CPSetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam
                            pbData, 11);
                     pCryptKey->dwSaltLen = 11;
                     setup_key(pCryptKey);
-                    /* Strange but true: salt length reset to 0 after setting
-                     * it via KP_SALT.
-                     */
-                    pCryptKey->dwSaltLen = 0;
+                    /* After setting the salt value if the provider is not base or
+                     * strong the salt length will be reset. */
+                    if (pKeyContainer->dwPersonality != RSAENH_PERSONALITY_BASE &&
+                        pKeyContainer->dwPersonality != RSAENH_PERSONALITY_STRONG)
+                        pCryptKey->dwSaltLen = 0;
                     break;
+                }
                 default:
                     SetLastError(NTE_BAD_KEY);
                     return FALSE;
diff --git a/dlls/rsaenh/tests/rsaenh.c b/dlls/rsaenh/tests/rsaenh.c
index 00be8a7..072f08a 100644
--- a/dlls/rsaenh/tests/rsaenh.c
+++ b/dlls/rsaenh/tests/rsaenh.c
@@ -62,7 +62,7 @@ static const cryptdata cTestData[4] = {
        12,12,16}
 };
 
-static int win2k;
+static int win2k, nt4;
 
 /*
  * 1. Take the MD5 Hash of the container name (with an extra null byte)
@@ -249,7 +249,10 @@ static void test_prov(void)
     SetLastError(0xdeadbeef);
     result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
     if (!result && GetLastError() == NTE_BAD_TYPE)
+    {
         skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
+        nt4++;
+    }
     else
         ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
     
@@ -1472,16 +1475,16 @@ static void test_rc2(void)
         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
         ok(result, "%08x\n", GetLastError());
 
-        /* Setting the salt also succeeds... */
+        /* Setting the salt value will not reset the salt length in base or strong providers */
         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
         ok(result, "setting salt failed: %08x\n", GetLastError());
-        /* but the resulting salt length is now zero? */
         dwLen = 0;
         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
         ok(result, "%08x\n", GetLastError());
-        ok(dwLen == 0 ||
-           broken(dwLen == 11), /* Win9x/WinMe/NT4 */
-           "unexpected salt length %d\n", dwLen);
+        if (BASE_PROV || STRONG_PROV)
+            ok(dwLen == 11, "expected salt length 11, got %d\n", dwLen);
+        else
+            ok(dwLen == 0 || broken(nt4 && dwLen == 11), "expected salt length 0, got %d\n", dwLen);
         /* What sizes salt can I set? */
         salt.pbData = pbData;
         for (i=0; i<24; i++)
@@ -1719,16 +1722,16 @@ static void test_rc4(void)
         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
         ok(result, "%08x\n", GetLastError());
 
-        /* Setting the salt also succeeds... */
+        /* Setting the salt value will not reset the salt length in base or strong providers */
         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
         ok(result, "setting salt failed: %08x\n", GetLastError());
-        /* but the resulting salt length is now zero? */
         dwLen = 0;
         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
         ok(result, "%08x\n", GetLastError());
-        ok(dwLen == 0 ||
-           broken(dwLen == 11), /* Win9x/WinMe/NT4 */
-           "unexpected salt length %d\n", dwLen);
+        if (BASE_PROV || STRONG_PROV || nt4)
+            ok(dwLen == 11, "expected salt length 11, got %d\n", dwLen);
+        else
+            ok(dwLen == 0 || broken(nt4 && dwLen == 11), "expected salt length 0, got %d\n", dwLen);
         /* What sizes salt can I set? */
         salt.pbData = pbData;
         for (i=0; i<24; i++)


More information about the wine-patches mailing list