Module: wine Branch: master Commit: e8ea6700ca4f33765d1dedf5f27777791264b59a URL: http://source.winehq.org/git/wine.git/?a=commit;h=e8ea6700ca4f33765d1dedf5f2...
Author: Juan Lang juan.lang@gmail.com Date: Wed Jan 28 21:18:32 2009 -0800
rsaenh: Honor a key's permissions when exporting a private key.
---
dlls/rsaenh/rsaenh.c | 103 +++++++++++++++++++++++++++++-------------- dlls/rsaenh/tests/rsaenh.c | 2 - 2 files changed, 69 insertions(+), 36 deletions(-)
diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c index cccbcf3..059dad2 100644 --- a/dlls/rsaenh/rsaenh.c +++ b/dlls/rsaenh/rsaenh.c @@ -311,13 +311,12 @@ RSAENH_CPDestroyHash( HCRYPTHASH hHash );
-BOOL WINAPI -RSAENH_CPExportKey( - HCRYPTPROV hProv, - HCRYPTKEY hKey, +static BOOL crypt_export_key( + CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey, DWORD dwBlobType, DWORD dwFlags, + BOOL force, BYTE *pbData, DWORD *pdwDataLen ); @@ -911,14 +910,13 @@ static void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, LPCSTR szValueName, D if (lookup_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pKey)) { - if (RSAENH_CPExportKey(pKey->hProv, hCryptKey, 0, PRIVATEKEYBLOB, 0, 0, - &dwLen)) + if (crypt_export_key(pKey, 0, PRIVATEKEYBLOB, 0, TRUE, 0, &dwLen)) { pbKey = HeapAlloc(GetProcessHeap(), 0, dwLen); if (pbKey) { - if (RSAENH_CPExportKey(pKey->hProv, hCryptKey, 0, - PRIVATEKEYBLOB, 0, pbKey, &dwLen)) + if (crypt_export_key(pKey, 0, PRIVATEKEYBLOB, 0, TRUE, pbKey, + &dwLen)) { blobIn.pbData = pbKey; blobIn.cbData = dwLen; @@ -2282,8 +2280,8 @@ static BOOL crypt_export_public_key(CRYPTKEY *pCryptKey, BYTE *pbData, return TRUE; }
-static BOOL crypt_export_private_key(CRYPTKEY *pCryptKey, BYTE *pbData, - DWORD *pdwDataLen) +static BOOL crypt_export_private_key(CRYPTKEY *pCryptKey, BOOL force, + BYTE *pbData, DWORD *pdwDataLen) { BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData; RSAPUBKEY *pRSAPubKey = (RSAPUBKEY*)(pBlobHeader+1); @@ -2293,6 +2291,11 @@ static BOOL crypt_export_private_key(CRYPTKEY *pCryptKey, BYTE *pbData, SetLastError(NTE_BAD_KEY); return FALSE; } + if (!force && !(pCryptKey->dwPermissions & CRYPT_EXPORT)) + { + SetLastError(NTE_BAD_KEY_STATE); + return FALSE; + }
dwDataLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + 2 * pCryptKey->dwKeyLen + 5 * ((pCryptKey->dwKeyLen + 1) >> 1); @@ -2319,16 +2322,19 @@ static BOOL crypt_export_private_key(CRYPTKEY *pCryptKey, BYTE *pbData, }
/****************************************************************************** - * CPExportKey (RSAENH.@) + * crypt_export_key [Internal] * - * Export a key into a binary large object (BLOB). + * Export a key into a binary large object (BLOB). Called by CPExportKey and + * by store_key_pair. * * PARAMS - * hProv [I] Key container from which a key is to be exported. - * hKey [I] Key to be exported. + * pCryptKey [I] Key to be exported. * hPubKey [I] Key used to encrypt sensitive BLOB data. * dwBlobType [I] SIMPLEBLOB, PUBLICKEYBLOB or PRIVATEKEYBLOB. * dwFlags [I] Currently none defined. + * force [I] If TRUE, the key is written no matter what the key's + * permissions are. Otherwise the key's permissions are + * checked before exporting. * pbData [O] Pointer to a buffer where the BLOB will be written to. * pdwDataLen [I/O] I: Size of buffer at pbData, O: Size of BLOB * @@ -2336,26 +2342,12 @@ static BOOL crypt_export_private_key(CRYPTKEY *pCryptKey, BYTE *pbData, * Success: TRUE. * Failure: FALSE. */ -BOOL WINAPI RSAENH_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubKey, - DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) +static BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey, + DWORD dwBlobType, DWORD dwFlags, BOOL force, + BYTE *pbData, DWORD *pdwDataLen) { - CRYPTKEY *pCryptKey, *pPubKey; + CRYPTKEY *pPubKey;
- TRACE("(hProv=%08lx, hKey=%08lx, hPubKey=%08lx, dwBlobType=%08x, dwFlags=%08x, pbData=%p," - "pdwDataLen=%p)\n", hProv, hKey, hPubKey, dwBlobType, dwFlags, pbData, pdwDataLen); - - if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) - { - SetLastError(NTE_BAD_UID); - return FALSE; - } - - if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey)) - { - SetLastError(NTE_BAD_KEY); - return FALSE; - } - if (dwFlags & CRYPT_SSL2_FALLBACK) { if (pCryptKey->aiAlgid != CALG_SSL2_MASTER) { SetLastError(NTE_BAD_KEY); @@ -2370,7 +2362,8 @@ BOOL WINAPI RSAENH_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubK SetLastError(NTE_BAD_PUBLIC_KEY); /* FIXME: error_code? */ return FALSE; } - return crypt_export_simple(pCryptKey, pPubKey, dwFlags, pbData, pdwDataLen); + return crypt_export_simple(pCryptKey, pPubKey, dwFlags, pbData, + pdwDataLen);
case PUBLICKEYBLOB: if (is_valid_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY)) { @@ -2381,7 +2374,7 @@ BOOL WINAPI RSAENH_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubK return crypt_export_public_key(pCryptKey, pbData, pdwDataLen);
case PRIVATEKEYBLOB: - return crypt_export_private_key(pCryptKey, pbData, pdwDataLen); + return crypt_export_private_key(pCryptKey, force, pbData, pdwDataLen);
default: SetLastError(NTE_BAD_TYPE); /* FIXME: error code? */ @@ -2390,6 +2383,48 @@ BOOL WINAPI RSAENH_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubK }
/****************************************************************************** + * CPExportKey (RSAENH.@) + * + * Export a key into a binary large object (BLOB). + * + * PARAMS + * hProv [I] Key container from which a key is to be exported. + * hKey [I] Key to be exported. + * hPubKey [I] Key used to encrypt sensitive BLOB data. + * dwBlobType [I] SIMPLEBLOB, PUBLICKEYBLOB or PRIVATEKEYBLOB. + * dwFlags [I] Currently none defined. + * pbData [O] Pointer to a buffer where the BLOB will be written to. + * pdwDataLen [I/O] I: Size of buffer at pbData, O: Size of BLOB + * + * RETURNS + * Success: TRUE. + * Failure: FALSE. + */ +BOOL WINAPI RSAENH_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubKey, + DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) +{ + CRYPTKEY *pCryptKey; + + TRACE("(hProv=%08lx, hKey=%08lx, hPubKey=%08lx, dwBlobType=%08x, dwFlags=%08x, pbData=%p," + "pdwDataLen=%p)\n", hProv, hKey, hPubKey, dwBlobType, dwFlags, pbData, pdwDataLen); + + if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) + { + SetLastError(NTE_BAD_UID); + return FALSE; + } + + if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey)) + { + SetLastError(NTE_BAD_KEY); + return FALSE; + } + + return crypt_export_key(pCryptKey, hPubKey, dwBlobType, dwFlags, FALSE, + pbData, pdwDataLen); +} + +/****************************************************************************** * CPImportKey (RSAENH.@) * * Import a BLOB'ed key into a key container. diff --git a/dlls/rsaenh/tests/rsaenh.c b/dlls/rsaenh/tests/rsaenh.c index e13bc1c..57ca35f 100644 --- a/dlls/rsaenh/tests/rsaenh.c +++ b/dlls/rsaenh/tests/rsaenh.c @@ -1574,7 +1574,6 @@ static void test_rsa_encrypt(void) /* but its private key may not be. */ SetLastError(0xdeadbeef); result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen); - todo_wine ok(!result && GetLastError() == NTE_BAD_KEY_STATE, "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError()); /* Setting the permissions of the key exchange key isn't allowed, either. */ @@ -1606,7 +1605,6 @@ static void test_rsa_encrypt(void) /* but its private key may not be. */ SetLastError(0xdeadbeef); result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen); - todo_wine ok(!result && GetLastError() == NTE_BAD_KEY_STATE, "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError()); /* Setting the permissions of the signature key isn't allowed, either. */