Juan Lang : rsaenh: Honor a key's permissions when exporting a private key.
Alexandre Julliard
julliard at winehq.org
Thu Jan 29 09:14:59 CST 2009
Module: wine
Branch: master
Commit: e8ea6700ca4f33765d1dedf5f27777791264b59a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e8ea6700ca4f33765d1dedf5f27777791264b59a
Author: Juan Lang <juan.lang at 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. */
More information about the wine-cvs
mailing list