Juan Lang : rsaenh: Infer private exponent length from data length.

Alexandre Julliard julliard at winehq.org
Tue Nov 1 13:23:20 CDT 2011


Module: wine
Branch: master
Commit: 2d658db553f1c9df313a4bfcd2c06618997ef5e6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2d658db553f1c9df313a4bfcd2c06618997ef5e6

Author: Juan Lang <juan.lang at gmail.com>
Date:   Mon Oct 31 10:44:23 2011 -0700

rsaenh: Infer private exponent length from data length.

---

 dlls/rsaenh/implglue.c     |    8 ++++++--
 dlls/rsaenh/implglue.h     |    2 +-
 dlls/rsaenh/rsaenh.c       |    6 +++---
 dlls/rsaenh/tests/rsaenh.c |    1 -
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/dlls/rsaenh/implglue.c b/dlls/rsaenh/implglue.c
index c217007..2d5a1b4 100644
--- a/dlls/rsaenh/implglue.c
+++ b/dlls/rsaenh/implglue.c
@@ -482,7 +482,7 @@ BOOL export_private_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD
 }
 
 BOOL import_private_key_impl(CONST BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, 
-                             DWORD dwPubExp)
+                             DWORD dwDataLen, DWORD dwPubExp)
 {
     BYTE *pbTemp, *pbBigNum;
 
@@ -496,7 +496,7 @@ BOOL import_private_key_impl(CONST BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD
 
     pbTemp = HeapAlloc(GetProcessHeap(), 0, 2*dwKeyLen+5*((dwKeyLen+1)>>1));
     if (!pbTemp) return FALSE;
-    memcpy(pbTemp, pbSrc, 2*dwKeyLen+5*((dwKeyLen+1)>>1));
+    memcpy(pbTemp, pbSrc, min(dwDataLen, 2*dwKeyLen+5*((dwKeyLen+1)>>1)));
     pbBigNum = pbTemp;
 
     pKeyContext->rsa.type = PK_PRIVATE;
@@ -518,6 +518,10 @@ BOOL import_private_key_impl(CONST BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD
     reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
     mp_read_unsigned_bin(&pKeyContext->rsa.qP, pbBigNum, (dwKeyLen+1)>>1);
     pbBigNum += (dwKeyLen+1)>>1;
+    /* The size of the private exponent d is inferred from the remaining
+     * data length.
+     */
+    dwKeyLen = min(dwKeyLen, dwDataLen - (pbBigNum - pbTemp));
     reverse_bytes(pbBigNum, dwKeyLen);
     mp_read_unsigned_bin(&pKeyContext->rsa.d, pbBigNum, dwKeyLen);
     mp_set_int(&pKeyContext->rsa.e, dwPubExp);
diff --git a/dlls/rsaenh/implglue.h b/dlls/rsaenh/implglue.h
index c07a279..efb5891 100644
--- a/dlls/rsaenh/implglue.h
+++ b/dlls/rsaenh/implglue.h
@@ -98,7 +98,7 @@ BOOL import_public_key_impl(CONST BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD d
 BOOL export_private_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
                              DWORD *pdwPubExp) DECLSPEC_HIDDEN;
 BOOL import_private_key_impl(CONST BYTE* pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, 
-                             DWORD dwPubExp) DECLSPEC_HIDDEN;
+                             DWORD dwDataLen, DWORD dwPubExp) DECLSPEC_HIDDEN;
 
 BOOL gen_rand_impl(BYTE *pbBuffer, DWORD dwLen) DECLSPEC_HIDDEN;
 
diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c
index f332cfb..fc04579 100644
--- a/dlls/rsaenh/rsaenh.c
+++ b/dlls/rsaenh/rsaenh.c
@@ -2745,10 +2745,10 @@ static BOOL import_private_key(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDat
         return FALSE;
     }
     if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
-            (2 * pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4))))
+            (pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4))))
     {
         DWORD expectedLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
-            (2 * pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4));
+            (pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4));
 
         ERR("blob too short for pub key: expect %d, got %d\n",
             expectedLen, dwDataLen);
@@ -2760,7 +2760,7 @@ static BOOL import_private_key(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDat
     if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE;
     setup_key(pCryptKey);
     ret = import_private_key_impl((CONST BYTE*)(pRSAPubKey+1), &pCryptKey->context,
-                                   pRSAPubKey->bitlen/8, pRSAPubKey->pubexp);
+                                   pRSAPubKey->bitlen/8, dwDataLen, pRSAPubKey->pubexp);
     if (ret) {
         if (dwFlags & CRYPT_EXPORTABLE)
             pCryptKey->dwPermissions |= CRYPT_EXPORT;
diff --git a/dlls/rsaenh/tests/rsaenh.c b/dlls/rsaenh/tests/rsaenh.c
index 58e6eb8..4af3cdcc 100644
--- a/dlls/rsaenh/tests/rsaenh.c
+++ b/dlls/rsaenh/tests/rsaenh.c
@@ -1573,7 +1573,6 @@ static void test_import_private(void)
     for (; dwLen < sizeof(abPlainPrivateKey); dwLen++)
     {
         result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
-        todo_wine
         ok(result, "CryptImportKey failed at size %d: %d (%08x)\n", dwLen,
            GetLastError(), GetLastError());
         if (result)




More information about the wine-cvs mailing list