--- dlls/rsaenh/cryptoprovutils.c | 212 ++++++++++++++++++++++++++++++++ dlls/rsaenh/cryptoprovutils.h | 7 ++ dlls/rsaenh/rsaenh.c | 224 +--------------------------------- 3 files changed, 220 insertions(+), 223 deletions(-)
diff --git a/dlls/rsaenh/cryptoprovutils.c b/dlls/rsaenh/cryptoprovutils.c index 44bbc923b8..7262ead819 100644 --- a/dlls/rsaenh/cryptoprovutils.c +++ b/dlls/rsaenh/cryptoprovutils.c @@ -319,3 +319,215 @@ void store_key_container_permissions(KEYCONTAINER *pKeyContainer) } }
+/****************************************************************************** + * release_key_container_keys [Internal] + * + * Releases key container's keys. + * + * PARAMS + * pKeyContainer [I] Pointer to the key container whose keys are to be released. + */ +void release_key_container_keys(KEYCONTAINER *pKeyContainer) +{ + release_handle(&handle_table, pKeyContainer->hKeyExchangeKeyPair, + RSAENH_MAGIC_KEY); + release_handle(&handle_table, pKeyContainer->hSignatureKeyPair, + RSAENH_MAGIC_KEY); +} + +/****************************************************************************** + * destroy_key_container [Internal] + * + * Destructor for key containers. + * + * PARAMS + * pObjectHdr [I] Pointer to the key container to be destroyed. + */ +void destroy_key_container(OBJECTHDR *pObjectHdr) +{ + KEYCONTAINER *pKeyContainer = (KEYCONTAINER*)pObjectHdr; + + if (!(pKeyContainer->dwFlags & CRYPT_VERIFYCONTEXT)) + { + store_key_container_keys(pKeyContainer); + store_key_container_permissions(pKeyContainer); + release_key_container_keys(pKeyContainer); + } + else + release_key_container_keys(pKeyContainer); + HeapFree( GetProcessHeap(), 0, pKeyContainer ); +} + +/****************************************************************************** + * read_key_value [Internal] + * + * Reads a key pair value from the registry + * + * PARAMS + * hKeyContainer [I] Crypt provider to use to import the key + * hKey [I] Registry key from which to read the key pair + * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE + * dwFlags [I] Flags for unprotecting the key + * phCryptKey [O] Returned key + */ +BOOL read_key_value(HCRYPTPROV hKeyContainer, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags, HCRYPTKEY *phCryptKey) +{ + LPCSTR szValueName; + DWORD dwValueType, dwLen; + BYTE *pbKey; + DATA_BLOB blobIn, blobOut; + BOOL ret = FALSE; + + if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec))) + return FALSE; + if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType, NULL, &dwLen) == + ERROR_SUCCESS) + { + pbKey = HeapAlloc(GetProcessHeap(), 0, dwLen); + if (pbKey) + { + if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType, pbKey, &dwLen) == + ERROR_SUCCESS) + { + blobIn.pbData = pbKey; + blobIn.cbData = dwLen; + + if (CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL, + dwFlags, &blobOut)) + { + ret = import_key(hKeyContainer, blobOut.pbData, blobOut.cbData, 0, 0, + FALSE, phCryptKey); + LocalFree(blobOut.pbData); + } + } + HeapFree(GetProcessHeap(), 0, pbKey); + } + } + if (ret) + { + CRYPTKEY *pKey; + + if (lookup_handle(&handle_table, *phCryptKey, RSAENH_MAGIC_KEY, + (OBJECTHDR**)&pKey)) + { + if ((szValueName = map_key_spec_to_permissions_name(dwKeySpec))) + { + dwLen = sizeof(pKey->dwPermissions); + RegQueryValueExA(hKey, szValueName, 0, NULL, + (BYTE *)&pKey->dwPermissions, &dwLen); + } + } + } + return ret; +} + +/****************************************************************************** + * read_key_container [Internal] + * + * Tries to read the persistent state of the key container (mainly the signature + * and key exchange private keys) given by pszContainerName. + * + * PARAMS + * pszContainerName [I] Name of the key container to read from the registry + * pVTable [I] Pointer to context data provided by the operating system + * + * RETURNS + * Success: Handle to the key container read from the registry + * Failure: INVALID_HANDLE_VALUE + */ +HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable) +{ + HKEY hKey; + KEYCONTAINER *pKeyContainer; + HCRYPTPROV hKeyContainer; + HCRYPTKEY hCryptKey; + + if (!open_container_key(pszContainerName, dwFlags, KEY_READ, &hKey)) + { + SetLastError(NTE_BAD_KEYSET); + return (HCRYPTPROV)INVALID_HANDLE_VALUE; + } + + hKeyContainer = new_key_container(pszContainerName, dwFlags, pVTable); + if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE) + { + DWORD dwProtectFlags = (dwFlags & CRYPT_MACHINE_KEYSET) ? + CRYPTPROTECT_LOCAL_MACHINE : 0; + + if (!lookup_handle(&handle_table, hKeyContainer, RSAENH_MAGIC_CONTAINER, + (OBJECTHDR**)&pKeyContainer)) + return (HCRYPTPROV)INVALID_HANDLE_VALUE; + + /* read_key_value calls import_key, which calls import_private_key, + * which implicitly installs the key value into the appropriate key + * container key. Thus the ref count is incremented twice, once for + * the output key value, and once for the implicit install, and needs + * to be decremented to balance the two. + */ + if (read_key_value(hKeyContainer, hKey, AT_KEYEXCHANGE, + dwProtectFlags, &hCryptKey)) + release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY); + if (read_key_value(hKeyContainer, hKey, AT_SIGNATURE, + dwProtectFlags, &hCryptKey)) + release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY); + } + + return hKeyContainer; +} + +/****************************************************************************** + * new_key_container [Internal] + * + * Create a new key container. The personality (RSA Base, Strong or Enhanced CP) + * of the CSP is determined via the pVTable->pszProvName string. + * + * PARAMS + * pszContainerName [I] Name of the key container. + * pVTable [I] Callback functions and context info provided by the OS + * + * RETURNS + * Success: Handle to the new key container. + * Failure: INVALID_HANDLE_VALUE + */ +HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable) +{ + KEYCONTAINER *pKeyContainer; + HCRYPTPROV hKeyContainer; + DWORD i; + + hKeyContainer = new_object(&handle_table, sizeof(KEYCONTAINER), RSAENH_MAGIC_CONTAINER, + destroy_key_container, (OBJECTHDR**)&pKeyContainer); + if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE) + { + lstrcpynA(pKeyContainer->szName, pszContainerName, MAX_PATH); + pKeyContainer->dwFlags = dwFlags; + pKeyContainer->dwEnumAlgsCtr = 0; + pKeyContainer->hKeyExchangeKeyPair = (HCRYPTKEY)INVALID_HANDLE_VALUE; + pKeyContainer->hSignatureKeyPair = (HCRYPTKEY)INVALID_HANDLE_VALUE; + if (pVTable && pVTable->pszProvName) { + lstrcpynA(pKeyContainer->szProvName, pVTable->pszProvName, MAX_PATH); + pKeyContainer->dwPersonality + = aProvNamePersonalityPairs[0].dwPersonality; + for (i = 1; i < dwNProvNamePersonalityPairs; i++) { + if (!strcmp(pVTable->pszProvName, + aProvNamePersonalityPairs[i].pszProvName)) { + pKeyContainer->dwPersonality + = aProvNamePersonalityPairs[i].dwPersonality; + break; + } + } + } + + /* The new key container has to be inserted into the CSP immediately + * after creation to be available for CPGetProvParam's PP_ENUMCONTAINERS. */ + if (!(dwFlags & CRYPT_VERIFYCONTEXT)) { + HKEY hKey; + + if (create_container_key(pKeyContainer, KEY_WRITE, &hKey)) + RegCloseKey(hKey); + } + } + + return hKeyContainer; +} + diff --git a/dlls/rsaenh/cryptoprovutils.h b/dlls/rsaenh/cryptoprovutils.h index 4b5fcf2f22..f745ada8d4 100644 --- a/dlls/rsaenh/cryptoprovutils.h +++ b/dlls/rsaenh/cryptoprovutils.h @@ -81,4 +81,11 @@ void store_key_container_keys(KEYCONTAINER *pKeyContainer); LPCSTR map_key_spec_to_permissions_name(DWORD dwKeySpec); void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec); void store_key_container_permissions(KEYCONTAINER *pKeyContainer); +void release_key_container_keys(KEYCONTAINER *pKeyContainer); +void destroy_key_container(OBJECTHDR *pObjectHdr); +BOOL read_key_value(HCRYPTPROV hKeyContainer, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags, HCRYPTKEY *phCryptKey); +HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable); +HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable); +BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, + DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey); #endif /* __WINE_CRYPTOPROVUTILS_H */ diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c index 5557068813..310863a514 100644 --- a/dlls/rsaenh/rsaenh.c +++ b/dlls/rsaenh/rsaenh.c @@ -255,16 +255,6 @@ RSAENH_CPDestroyHash( HCRYPTHASH hHash );
-static BOOL import_key( - HCRYPTPROV hProv, - const BYTE *pbData, - DWORD dwDataLen, - HCRYPTKEY hPubKey, - DWORD dwFlags, - BOOL fStoreKey, - HCRYPTKEY *phKey -); - BOOL WINAPI RSAENH_CPHashData( HCRYPTPROV hProv, @@ -862,218 +852,6 @@ static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTK return hCryptKey; }
-/****************************************************************************** - * release_key_container_keys [Internal] - * - * Releases key container's keys. - * - * PARAMS - * pKeyContainer [I] Pointer to the key container whose keys are to be released. - */ -static void release_key_container_keys(KEYCONTAINER *pKeyContainer) -{ - release_handle(&handle_table, pKeyContainer->hKeyExchangeKeyPair, - RSAENH_MAGIC_KEY); - release_handle(&handle_table, pKeyContainer->hSignatureKeyPair, - RSAENH_MAGIC_KEY); -} - -/****************************************************************************** - * destroy_key_container [Internal] - * - * Destructor for key containers. - * - * PARAMS - * pObjectHdr [I] Pointer to the key container to be destroyed. - */ -static void destroy_key_container(OBJECTHDR *pObjectHdr) -{ - KEYCONTAINER *pKeyContainer = (KEYCONTAINER*)pObjectHdr; - - if (!(pKeyContainer->dwFlags & CRYPT_VERIFYCONTEXT)) - { - store_key_container_keys(pKeyContainer); - store_key_container_permissions(pKeyContainer); - release_key_container_keys(pKeyContainer); - } - else - release_key_container_keys(pKeyContainer); - HeapFree( GetProcessHeap(), 0, pKeyContainer ); -} - -/****************************************************************************** - * new_key_container [Internal] - * - * Create a new key container. The personality (RSA Base, Strong or Enhanced CP) - * of the CSP is determined via the pVTable->pszProvName string. - * - * PARAMS - * pszContainerName [I] Name of the key container. - * pVTable [I] Callback functions and context info provided by the OS - * - * RETURNS - * Success: Handle to the new key container. - * Failure: INVALID_HANDLE_VALUE - */ -static HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable) -{ - KEYCONTAINER *pKeyContainer; - HCRYPTPROV hKeyContainer; - DWORD i; - - hKeyContainer = new_object(&handle_table, sizeof(KEYCONTAINER), RSAENH_MAGIC_CONTAINER, - destroy_key_container, (OBJECTHDR**)&pKeyContainer); - if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE) - { - lstrcpynA(pKeyContainer->szName, pszContainerName, MAX_PATH); - pKeyContainer->dwFlags = dwFlags; - pKeyContainer->dwEnumAlgsCtr = 0; - pKeyContainer->hKeyExchangeKeyPair = (HCRYPTKEY)INVALID_HANDLE_VALUE; - pKeyContainer->hSignatureKeyPair = (HCRYPTKEY)INVALID_HANDLE_VALUE; - if (pVTable && pVTable->pszProvName) { - lstrcpynA(pKeyContainer->szProvName, pVTable->pszProvName, MAX_PATH); - pKeyContainer->dwPersonality - = aProvNamePersonalityPairs[0].dwPersonality; - for (i = 1; i < dwNProvNamePersonalityPairs; i++) { - if (!strcmp(pVTable->pszProvName, - aProvNamePersonalityPairs[i].pszProvName)) { - pKeyContainer->dwPersonality - = aProvNamePersonalityPairs[i].dwPersonality; - break; - } - } - } - - /* The new key container has to be inserted into the CSP immediately - * after creation to be available for CPGetProvParam's PP_ENUMCONTAINERS. */ - if (!(dwFlags & CRYPT_VERIFYCONTEXT)) { - HKEY hKey; - - if (create_container_key(pKeyContainer, KEY_WRITE, &hKey)) - RegCloseKey(hKey); - } - } - - return hKeyContainer; -} - -/****************************************************************************** - * read_key_value [Internal] - * - * Reads a key pair value from the registry - * - * PARAMS - * hKeyContainer [I] Crypt provider to use to import the key - * hKey [I] Registry key from which to read the key pair - * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE - * dwFlags [I] Flags for unprotecting the key - * phCryptKey [O] Returned key - */ -static BOOL read_key_value(HCRYPTPROV hKeyContainer, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags, HCRYPTKEY *phCryptKey) -{ - LPCSTR szValueName; - DWORD dwValueType, dwLen; - BYTE *pbKey; - DATA_BLOB blobIn, blobOut; - BOOL ret = FALSE; - - if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec))) - return FALSE; - if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType, NULL, &dwLen) == - ERROR_SUCCESS) - { - pbKey = HeapAlloc(GetProcessHeap(), 0, dwLen); - if (pbKey) - { - if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType, pbKey, &dwLen) == - ERROR_SUCCESS) - { - blobIn.pbData = pbKey; - blobIn.cbData = dwLen; - - if (CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL, - dwFlags, &blobOut)) - { - ret = import_key(hKeyContainer, blobOut.pbData, blobOut.cbData, 0, 0, - FALSE, phCryptKey); - LocalFree(blobOut.pbData); - } - } - HeapFree(GetProcessHeap(), 0, pbKey); - } - } - if (ret) - { - CRYPTKEY *pKey; - - if (lookup_handle(&handle_table, *phCryptKey, RSAENH_MAGIC_KEY, - (OBJECTHDR**)&pKey)) - { - if ((szValueName = map_key_spec_to_permissions_name(dwKeySpec))) - { - dwLen = sizeof(pKey->dwPermissions); - RegQueryValueExA(hKey, szValueName, 0, NULL, - (BYTE *)&pKey->dwPermissions, &dwLen); - } - } - } - return ret; -} - -/****************************************************************************** - * read_key_container [Internal] - * - * Tries to read the persistent state of the key container (mainly the signature - * and key exchange private keys) given by pszContainerName. - * - * PARAMS - * pszContainerName [I] Name of the key container to read from the registry - * pVTable [I] Pointer to context data provided by the operating system - * - * RETURNS - * Success: Handle to the key container read from the registry - * Failure: INVALID_HANDLE_VALUE - */ -static HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable) -{ - HKEY hKey; - KEYCONTAINER *pKeyContainer; - HCRYPTPROV hKeyContainer; - HCRYPTKEY hCryptKey; - - if (!open_container_key(pszContainerName, dwFlags, KEY_READ, &hKey)) - { - SetLastError(NTE_BAD_KEYSET); - return (HCRYPTPROV)INVALID_HANDLE_VALUE; - } - - hKeyContainer = new_key_container(pszContainerName, dwFlags, pVTable); - if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE) - { - DWORD dwProtectFlags = (dwFlags & CRYPT_MACHINE_KEYSET) ? - CRYPTPROTECT_LOCAL_MACHINE : 0; - - if (!lookup_handle(&handle_table, hKeyContainer, RSAENH_MAGIC_CONTAINER, - (OBJECTHDR**)&pKeyContainer)) - return (HCRYPTPROV)INVALID_HANDLE_VALUE; - - /* read_key_value calls import_key, which calls import_private_key, - * which implicitly installs the key value into the appropriate key - * container key. Thus the ref count is incremented twice, once for - * the output key value, and once for the implicit install, and needs - * to be decremented to balance the two. - */ - if (read_key_value(hKeyContainer, hKey, AT_KEYEXCHANGE, - dwProtectFlags, &hCryptKey)) - release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY); - if (read_key_value(hKeyContainer, hKey, AT_SIGNATURE, - dwProtectFlags, &hCryptKey)) - release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY); - } - - return hKeyContainer; -} - /****************************************************************************** * build_hash_signature [Internal] * @@ -3001,7 +2779,7 @@ static BOOL import_plaintext_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwD * Success: TRUE. * Failure: FALSE. */ -static BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, +BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey) { KEYCONTAINER *pKeyContainer;