From 2d658db553f1c9df313a4bfcd2c06618997ef5e6 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Mon, 31 Oct 2011 10:44:23 -0700 Subject: [PATCH] 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 c217007221c..2d5a1b401ca 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 c07a27990c5..efb58918bc7 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 f332cfb16d7..fc04579d179 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 58e6eb8a0e2..4af3cdcc433 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)