Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/advapi32/crypt.c | 8 +------- dlls/advapi32/tests/crypt.c | 3 +++ 2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/dlls/advapi32/crypt.c b/dlls/advapi32/crypt.c index a9314d31472..79eeec98c2d 100644 --- a/dlls/advapi32/crypt.c +++ b/dlls/advapi32/crypt.c @@ -582,13 +582,7 @@ BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFl
TRACE("(0x%lx, %p, %08x)\n", hProv, pdwReserved, dwFlags);
- if (!pProv) - { - SetLastError(NTE_BAD_UID); - return FALSE; - } - - if (pProv->dwMagic != MAGIC_CRYPTPROV) + if (!pProv || pProv->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; diff --git a/dlls/advapi32/tests/crypt.c b/dlls/advapi32/tests/crypt.c index f34c99ee9bf..8d4f2ae5936 100644 --- a/dlls/advapi32/tests/crypt.c +++ b/dlls/advapi32/tests/crypt.c @@ -152,6 +152,9 @@ static void test_CryptReleaseContext(void) ret = CryptContextAddRef(prov, NULL, 0); ok(ret, "got %u\n", GetLastError());
+ ret = CryptContextAddRef(0, NULL, 0); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError()); + ret = CryptReleaseContext(prov, 0); ok(ret, "got %u\n", GetLastError());
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/advapi32/crypt.c | 412 ++++++++++++++++++++++-------------------- 1 file changed, 219 insertions(+), 193 deletions(-)
diff --git a/dlls/advapi32/crypt.c b/dlls/advapi32/crypt.c index 79eeec98c2d..91da4034405 100644 --- a/dlls/advapi32/crypt.c +++ b/dlls/advapi32/crypt.c @@ -57,6 +57,37 @@ static HWND crypt_hWindow; #define CRYPT_Alloc(size) (LocalAlloc(LMEM_ZEROINIT, size)) #define CRYPT_Free(buffer) (LocalFree(buffer))
+static void *pointer_from_handle(UINT_PTR handle, DWORD magic, DWORD invalid_handle_error_code) +{ + if (!handle) + { + SetLastError(invalid_handle_error_code); + return NULL; + } + if (*(DWORD *)handle != magic) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + return (void *)handle; +} + +static PCRYPTPROV provider_from_handle(HCRYPTPROV handle, DWORD invalid_handle_error_code) +{ + return pointer_from_handle(handle, MAGIC_CRYPTPROV, invalid_handle_error_code); +} + +static PCRYPTHASH hash_from_handle(HCRYPTHASH handle, DWORD invalid_handle_error_code) +{ + return pointer_from_handle(handle, MAGIC_CRYPTHASH, invalid_handle_error_code); +} + +static PCRYPTKEY key_from_handle(HCRYPTKEY handle, DWORD invalid_handle_error_code) +{ + return pointer_from_handle(handle, MAGIC_CRYPTKEY, invalid_handle_error_code); +} + static inline PWSTR CRYPT_GetProvKeyName(PCWSTR pProvName) { static const WCHAR KEYSTR[] = L"Software\Microsoft\Cryptography\Defaults\Provider\"; @@ -578,15 +609,12 @@ BOOL WINAPI CryptAcquireContextA (HCRYPTPROV *phProv, LPCSTR pszContainer, */ BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFlags) { - PCRYPTPROV pProv = (PCRYPTPROV)hProv; + PCRYPTPROV pProv = provider_from_handle(hProv, ERROR_INVALID_PARAMETER);
TRACE("(0x%lx, %p, %08x)\n", hProv, pdwReserved, dwFlags);
- if (!pProv || pProv->dwMagic != MAGIC_CRYPTPROV) - { - SetLastError(ERROR_INVALID_PARAMETER); + if (!pProv) return FALSE; - }
InterlockedIncrement(&pProv->refcount); return TRUE; @@ -607,22 +635,13 @@ BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFl */ BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags) { - PCRYPTPROV pProv = (PCRYPTPROV)hProv; + PCRYPTPROV pProv = provider_from_handle(hProv, ERROR_INVALID_PARAMETER); BOOL ret = TRUE;
TRACE("(0x%lx, %08x)\n", hProv, dwFlags);
if (!pProv) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - if (pProv->dwMagic != MAGIC_CRYPTPROV) - { - SetLastError(ERROR_INVALID_PARAMETER); return FALSE; - }
if (InterlockedDecrement(&pProv->refcount) == 0) { @@ -659,21 +678,12 @@ BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags) */ BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer) { - PCRYPTPROV prov = (PCRYPTPROV)hProv; + PCRYPTPROV prov = provider_from_handle(hProv, ERROR_INVALID_HANDLE);
TRACE("(0x%lx, %d, %p)\n", hProv, dwLen, pbBuffer);
- if (!hProv) - { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } - - if (prov->dwMagic != MAGIC_CRYPTPROV) - { - SetLastError(ERROR_INVALID_PARAMETER); + if (!prov) return FALSE; - }
return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer); } @@ -698,45 +708,51 @@ BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer) * If the algorithm is a keyed hash, hKey is the key. */ BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, - DWORD dwFlags, HCRYPTHASH *phHash) + DWORD dwFlags, HCRYPTHASH *phHash) { - PCRYPTPROV prov = (PCRYPTPROV)hProv; - PCRYPTKEY key = (PCRYPTKEY)hKey; - PCRYPTHASH hash; + PCRYPTKEY key = NULL; + PCRYPTPROV prov; + PCRYPTHASH hash;
- TRACE("(0x%lx, 0x%x, 0x%lx, %08x, %p)\n", hProv, Algid, hKey, dwFlags, phHash); + TRACE("(0x%lx, 0x%x, 0x%lx, %08x, %p)\n", hProv, Algid, hKey, dwFlags, phHash);
- if (!prov || !phHash || prov->dwMagic != MAGIC_CRYPTPROV || - (key && key->dwMagic != MAGIC_CRYPTKEY)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - if (dwFlags) - { - SetLastError(NTE_BAD_FLAGS); - return FALSE; - } - if ( !(hash = CRYPT_Alloc(sizeof(CRYPTHASH))) ) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } + if (!(prov = provider_from_handle(hProv, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (hKey && !(key = key_from_handle(hKey, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (!phHash) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (dwFlags) + { + SetLastError(NTE_BAD_FLAGS); + return FALSE; + } + if ( !(hash = CRYPT_Alloc(sizeof(CRYPTHASH))) ) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + }
- hash->pProvider = prov; - hash->dwMagic = MAGIC_CRYPTHASH; - if (prov->pFuncs->pCPCreateHash(prov->hPrivate, Algid, - key ? key->hPrivate : 0, 0, &hash->hPrivate)) + hash->pProvider = prov; + hash->dwMagic = MAGIC_CRYPTHASH; + if (prov->pFuncs->pCPCreateHash(prov->hPrivate, Algid, + key ? key->hPrivate : 0, 0, &hash->hPrivate)) { *phHash = (HCRYPTHASH)hash; return TRUE; }
- /* CSP error! */ - hash->dwMagic = 0; - CRYPT_Free(hash); - *phHash = 0; - return FALSE; + /* CSP error! */ + hash->dwMagic = 0; + CRYPT_Free(hash); + *phHash = 0; + return FALSE; }
/****************************************************************************** @@ -758,25 +774,29 @@ BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, * Failure: FALSE */ BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, - DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) + DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) { - PCRYPTPROV prov; - PCRYPTKEY key = (PCRYPTKEY)hKey; - PCRYPTHASH hash = (PCRYPTHASH)hHash; + PCRYPTHASH hash = NULL; + PCRYPTPROV prov; + PCRYPTKEY key;
- TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen); + TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
- if (!key || !pbData || !pdwDataLen || - !key->pProvider || key->dwMagic != MAGIC_CRYPTKEY || - key->pProvider->dwMagic != MAGIC_CRYPTPROV) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + if (!(key = key_from_handle(hKey, ERROR_INVALID_PARAMETER))) + return FALSE;
- prov = key->pProvider; - return prov->pFuncs->pCPDecrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0, - Final, dwFlags, pbData, pdwDataLen); + if (hHash && !(hash = hash_from_handle(hHash, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (!pbData || !pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + prov = key->pProvider; + return prov->pFuncs->pCPDecrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0, + Final, dwFlags, pbData, pdwDataLen); }
/****************************************************************************** @@ -796,43 +816,44 @@ BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, * Failure: FALSE */ BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, - DWORD dwFlags, HCRYPTKEY *phKey) + DWORD dwFlags, HCRYPTKEY *phKey) { - PCRYPTPROV prov = (PCRYPTPROV)hProv; - PCRYPTHASH hash = (PCRYPTHASH)hBaseData; - PCRYPTKEY key; + PCRYPTPROV prov; + PCRYPTHASH hash; + PCRYPTKEY key;
- TRACE("(0x%lx, 0x%08x, 0x%lx, 0x%08x, %p)\n", hProv, Algid, hBaseData, dwFlags, phKey); + TRACE("(0x%lx, 0x%08x, 0x%lx, 0x%08x, %p)\n", hProv, Algid, hBaseData, dwFlags, phKey);
- if (!prov || !hash) - { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } - if (!phKey || prov->dwMagic != MAGIC_CRYPTPROV || hash->dwMagic != MAGIC_CRYPTHASH) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } + if (!(prov = provider_from_handle(hProv, ERROR_INVALID_HANDLE))) + return FALSE;
- key->pProvider = prov; - key->dwMagic = MAGIC_CRYPTKEY; - if (prov->pFuncs->pCPDeriveKey(prov->hPrivate, Algid, hash->hPrivate, dwFlags, &key->hPrivate)) + if (!(hash = hash_from_handle(hBaseData, ERROR_INVALID_HANDLE))) + return FALSE; + + if (!phKey) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + key->pProvider = prov; + key->dwMagic = MAGIC_CRYPTKEY; + if (prov->pFuncs->pCPDeriveKey(prov->hPrivate, Algid, hash->hPrivate, dwFlags, &key->hPrivate)) { *phKey = (HCRYPTKEY)key; return TRUE; }
- /* CSP error! */ - key->dwMagic = 0; - CRYPT_Free(key); - *phKey = 0; - return FALSE; + /* CSP error! */ + key->dwMagic = 0; + CRYPT_Free(key); + *phKey = 0; + return FALSE; }
/****************************************************************************** @@ -849,20 +870,16 @@ BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData */ BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash) { - PCRYPTHASH hash = (PCRYPTHASH)hHash; + PCRYPTHASH hash; PCRYPTPROV prov; BOOL ret;
TRACE("(0x%lx)\n", hHash);
- if (!hash) - { - SetLastError(ERROR_INVALID_HANDLE); + if (!(hash = hash_from_handle(hHash, ERROR_INVALID_HANDLE))) return FALSE; - }
- if (!hash->pProvider || hash->dwMagic != MAGIC_CRYPTHASH || - hash->pProvider->dwMagic != MAGIC_CRYPTPROV) + if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -889,20 +906,16 @@ BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash) */ BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey) { - PCRYPTKEY key = (PCRYPTKEY)hKey; PCRYPTPROV prov; + PCRYPTKEY key; BOOL ret;
TRACE("(0x%lx)\n", hKey);
- if (!key) - { - SetLastError(ERROR_INVALID_HANDLE); + if (!(key = key_from_handle(hKey, ERROR_INVALID_HANDLE))) return FALSE; - }
- if (!key->pProvider || key->dwMagic != MAGIC_CRYPTKEY || - key->pProvider->dwMagic != MAGIC_CRYPTPROV) + if (!key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -938,9 +951,10 @@ BOOL WINAPI CryptDuplicateHash (HCRYPTHASH hHash, DWORD *pdwReserved,
TRACE("(0x%lx, %p, %08x, %p)\n", hHash, pdwReserved, dwFlags, phHash);
- orghash = (PCRYPTHASH)hHash; - if (!orghash || pdwReserved || !phHash || !orghash->pProvider || - orghash->dwMagic != MAGIC_CRYPTHASH || orghash->pProvider->dwMagic != MAGIC_CRYPTPROV) + if (!(orghash = hash_from_handle(hHash, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (pdwReserved || !phHash || !orghash->pProvider || orghash->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -993,10 +1007,10 @@ BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags
TRACE("(0x%lx, %p, %08x, %p)\n", hKey, pdwReserved, dwFlags, phKey);
- orgkey = (PCRYPTKEY)hKey; - if (!orgkey || pdwReserved || !phKey || !orgkey->pProvider || - orgkey->dwMagic != MAGIC_CRYPTKEY || - orgkey->pProvider->dwMagic != MAGIC_CRYPTPROV) + if (!(orgkey = key_from_handle(hKey, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (pdwReserved || !phKey || !orgkey->pProvider || orgkey->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -1053,14 +1067,19 @@ BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags BOOL WINAPI CryptEncrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen) { + PCRYPTHASH hash = NULL; PCRYPTPROV prov; - PCRYPTKEY key = (PCRYPTKEY)hKey; - PCRYPTHASH hash = (PCRYPTHASH)hHash; + PCRYPTKEY key;
TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p, %d)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
- if (!key || !pdwDataLen || !key->pProvider || - key->dwMagic != MAGIC_CRYPTKEY || key->pProvider->dwMagic != MAGIC_CRYPTPROV) + if (!(key = key_from_handle(hKey, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (hHash && !(hash = hash_from_handle(hHash, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (!pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -1361,12 +1380,17 @@ BOOL WINAPI CryptExportKey (HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) { PCRYPTPROV prov; - PCRYPTKEY key = (PCRYPTKEY)hKey, expkey = (PCRYPTKEY)hExpKey; + PCRYPTKEY key, expkey = NULL;
TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p)\n", hKey, hExpKey, dwBlobType, dwFlags, pbData, pdwDataLen);
- if (!key || !pdwDataLen || !key->pProvider || - key->dwMagic != MAGIC_CRYPTKEY || key->pProvider->dwMagic != MAGIC_CRYPTPROV) + if (!(key = key_from_handle(hKey, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (hExpKey && !(expkey = key_from_handle(hExpKey, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (!pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -1394,12 +1418,15 @@ BOOL WINAPI CryptExportKey (HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType, */ BOOL WINAPI CryptGenKey (HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey) { - PCRYPTPROV prov = (PCRYPTPROV)hProv; + PCRYPTPROV prov; PCRYPTKEY key;
TRACE("(0x%lx, %d, %08x, %p)\n", hProv, Algid, dwFlags, phKey);
- if (!phKey || !prov || prov->dwMagic != MAGIC_CRYPTPROV) + if (!(prov = provider_from_handle(hProv, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (!phKey) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -1554,12 +1581,15 @@ BOOL WINAPI CryptGetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags) { PCRYPTPROV prov; - PCRYPTHASH hash = (PCRYPTHASH)hHash; + PCRYPTHASH hash;
TRACE("(0x%lx, %d, %p, %p, %08x)\n", hHash, dwParam, pbData, pdwDataLen, dwFlags);
- if (!hash || !pdwDataLen || !hash->pProvider || - hash->dwMagic != MAGIC_CRYPTHASH || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) + if (!(hash = hash_from_handle(hHash, ERROR_INVALID_PARAMETER))) + return FALSE; + + + if (!pdwDataLen || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -1593,12 +1623,14 @@ BOOL WINAPI CryptGetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags) { PCRYPTPROV prov; - PCRYPTKEY key = (PCRYPTKEY)hKey; + PCRYPTKEY key;
TRACE("(0x%lx, %d, %p, %p, %08x)\n", hKey, dwParam, pbData, pdwDataLen, dwFlags);
- if (!key || !pdwDataLen || !key->pProvider || - key->dwMagic != MAGIC_CRYPTKEY || key->pProvider->dwMagic != MAGIC_CRYPTPROV) + if (!(key = key_from_handle(hKey, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (!pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -1631,15 +1663,12 @@ BOOL WINAPI CryptGetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, BOOL WINAPI CryptGetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags) { - PCRYPTPROV prov = (PCRYPTPROV)hProv; + PCRYPTPROV prov;
TRACE("(0x%lx, %d, %p, %p, %08x)\n", hProv, dwParam, pbData, pdwDataLen, dwFlags);
- if (!prov || prov->dwMagic != MAGIC_CRYPTPROV) - { - SetLastError(ERROR_INVALID_PARAMETER); + if (!(prov = provider_from_handle(hProv, ERROR_INVALID_PARAMETER))) return FALSE; - }
return prov->pFuncs->pCPGetProvParam(prov->hPrivate, dwParam, pbData, pdwDataLen, dwFlags); } @@ -1660,17 +1689,15 @@ BOOL WINAPI CryptGetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, */ BOOL WINAPI CryptGetUserKey (HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey) { - PCRYPTPROV prov = (PCRYPTPROV)hProv; + PCRYPTPROV prov; PCRYPTKEY key;
TRACE("(0x%lx, %d, %p)\n", hProv, dwKeySpec, phUserKey);
- if (!prov) - { - SetLastError(ERROR_INVALID_HANDLE); + if (!(prov = provider_from_handle(hProv, ERROR_INVALID_HANDLE))) return FALSE; - } - if (!phUserKey || prov->dwMagic != MAGIC_CRYPTPROV) + + if (!phUserKey) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -1713,18 +1740,15 @@ BOOL WINAPI CryptGetUserKey (HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUse */ BOOL WINAPI CryptHashData (HCRYPTHASH hHash, const BYTE *pbData, DWORD dwDataLen, DWORD dwFlags) { - PCRYPTHASH hash = (PCRYPTHASH)hHash; + PCRYPTHASH hash; PCRYPTPROV prov;
TRACE("(0x%lx, %p, %d, %08x)\n", hHash, pbData, dwDataLen, dwFlags);
- if (!hash) - { - SetLastError(ERROR_INVALID_HANDLE); + if (!(hash = hash_from_handle(hHash, ERROR_INVALID_HANDLE))) return FALSE; - } - if (!hash->pProvider || hash->dwMagic != MAGIC_CRYPTHASH || - hash->pProvider->dwMagic != MAGIC_CRYPTPROV) + + if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -1750,20 +1774,19 @@ BOOL WINAPI CryptHashData (HCRYPTHASH hHash, const BYTE *pbData, DWORD dwDataLen */ BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags) { - PCRYPTHASH hash = (PCRYPTHASH)hHash; - PCRYPTKEY key = (PCRYPTKEY)hKey; + PCRYPTHASH hash; + PCRYPTKEY key; PCRYPTPROV prov;
TRACE("(0x%lx, 0x%lx, %08x)\n", hHash, hKey, dwFlags);
- if (!hash || !key) - { - SetLastError(ERROR_INVALID_HANDLE); + if (!(hash = hash_from_handle(hHash, ERROR_INVALID_HANDLE))) return FALSE; - }
- if (!hash->pProvider || hash->dwMagic != MAGIC_CRYPTHASH || - hash->pProvider->dwMagic != MAGIC_CRYPTPROV || key->dwMagic != MAGIC_CRYPTKEY) + if (!(key = key_from_handle(hKey, ERROR_INVALID_HANDLE))) + return FALSE; + + if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -1793,14 +1816,18 @@ BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey) { - PCRYPTPROV prov = (PCRYPTPROV)hProv; - PCRYPTKEY pubkey = (PCRYPTKEY)hPubKey, importkey; + PCRYPTPROV prov; + PCRYPTKEY pubkey = NULL, importkey;
TRACE("(0x%lx, %p, %d, 0x%lx, %08x, %p)\n", hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey);
- if (!prov || !pbData || !dwDataLen || !phKey || - prov->dwMagic != MAGIC_CRYPTPROV || - (pubkey && pubkey->dwMagic != MAGIC_CRYPTKEY)) + if (!(prov = provider_from_handle(hProv, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (hPubKey && !(pubkey = key_from_handle(hPubKey, ERROR_INVALID_HANDLE))) + return FALSE; + + if (!pbData || !dwDataLen || !phKey) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -1851,19 +1878,16 @@ BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLe BOOL WINAPI CryptSignHashW (HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen) { - PCRYPTHASH hash = (PCRYPTHASH)hHash; + PCRYPTHASH hash; PCRYPTPROV prov;
TRACE("(0x%lx, %d, %s, %08x, %p, %p)\n", hHash, dwKeySpec, debugstr_w(sDescription), dwFlags, pbSignature, pdwSigLen);
- if (!hash) - { - SetLastError(ERROR_INVALID_HANDLE); + if (!(hash = hash_from_handle(hHash, ERROR_INVALID_HANDLE))) return FALSE; - } - if (!pdwSigLen || !hash->pProvider || hash->dwMagic != MAGIC_CRYPTHASH || - hash->pProvider->dwMagic != MAGIC_CRYPTPROV) + + if (!pdwSigLen || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -1913,12 +1937,14 @@ BOOL WINAPI CryptSignHashA (HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescripti BOOL WINAPI CryptSetHashParam (HCRYPTHASH hHash, DWORD dwParam, const BYTE *pbData, DWORD dwFlags) { PCRYPTPROV prov; - PCRYPTHASH hash = (PCRYPTHASH)hHash; + PCRYPTHASH hash;
TRACE("(0x%lx, %d, %p, %08x)\n", hHash, dwParam, pbData, dwFlags);
- if (!hash || !pbData || !hash->pProvider || - hash->dwMagic != MAGIC_CRYPTHASH || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) + if (!(hash = hash_from_handle(hHash, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (!pbData || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -1947,12 +1973,14 @@ BOOL WINAPI CryptSetHashParam (HCRYPTHASH hHash, DWORD dwParam, const BYTE *pbDa BOOL WINAPI CryptSetKeyParam (HCRYPTKEY hKey, DWORD dwParam, const BYTE *pbData, DWORD dwFlags) { PCRYPTPROV prov; - PCRYPTKEY key = (PCRYPTKEY)hKey; + PCRYPTKEY key;
TRACE("(0x%lx, %d, %p, %08x)\n", hKey, dwParam, pbData, dwFlags);
- if (!key || !pbData || !key->pProvider || - key->dwMagic != MAGIC_CRYPTKEY || key->pProvider->dwMagic != MAGIC_CRYPTPROV) + if (!(key = key_from_handle(hKey, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (!pbData || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -2120,20 +2148,13 @@ BOOL WINAPI CryptSetProviderExA (LPCSTR pszProvName, DWORD dwProvType, DWORD *pd */ BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, const BYTE *pbData, DWORD dwFlags) { - PCRYPTPROV prov = (PCRYPTPROV)hProv; + PCRYPTPROV prov;
TRACE("(0x%lx, %d, %p, %08x)\n", hProv, dwParam, pbData, dwFlags);
- if (!prov) - { - SetLastError(ERROR_INVALID_HANDLE); + if (!(prov = provider_from_handle(hProv, ERROR_INVALID_HANDLE))) return FALSE; - } - if (prov->dwMagic != MAGIC_CRYPTPROV) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + if (dwParam == PP_USE_HARDWARE_RNG) { FIXME("PP_USE_HARDWARE_RNG: What do I do with this?\n"); @@ -2180,15 +2201,20 @@ BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, const BYTE *pbDa BOOL WINAPI CryptVerifySignatureW (HCRYPTHASH hHash, const BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags) { - PCRYPTHASH hash = (PCRYPTHASH)hHash; - PCRYPTKEY key = (PCRYPTKEY)hPubKey; + PCRYPTHASH hash; + PCRYPTKEY key; PCRYPTPROV prov;
TRACE("(0x%lx, %p, %d, 0x%lx, %s, %08x)\n", hHash, pbSignature, dwSigLen, hPubKey, debugstr_w(sDescription), dwFlags);
- if (!hash || !key || key->dwMagic != MAGIC_CRYPTKEY || hash->dwMagic != MAGIC_CRYPTHASH || - !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV || + if (!(hash = hash_from_handle(hHash, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (!(key = key_from_handle(hPubKey, ERROR_INVALID_PARAMETER))) + return FALSE; + + if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) { SetLastError(ERROR_INVALID_PARAMETER);
Paul Gofman pgofman@codeweavers.com writes:
@@ -57,6 +57,37 @@ static HWND crypt_hWindow; #define CRYPT_Alloc(size) (LocalAlloc(LMEM_ZEROINIT, size)) #define CRYPT_Free(buffer) (LocalFree(buffer))
+static void *pointer_from_handle(UINT_PTR handle, DWORD magic, DWORD invalid_handle_error_code) +{
- if (!handle)
- {
SetLastError(invalid_handle_error_code);
return NULL;
- }
- if (*(DWORD *)handle != magic)
- {
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
- }
- return (void *)handle;
+}
+static PCRYPTPROV provider_from_handle(HCRYPTPROV handle, DWORD invalid_handle_error_code) +{
- return pointer_from_handle(handle, MAGIC_CRYPTPROV, invalid_handle_error_code);
+}
+static PCRYPTHASH hash_from_handle(HCRYPTHASH handle, DWORD invalid_handle_error_code) +{
- return pointer_from_handle(handle, MAGIC_CRYPTHASH, invalid_handle_error_code);
+}
+static PCRYPTKEY key_from_handle(HCRYPTKEY handle, DWORD invalid_handle_error_code) +{
- return pointer_from_handle(handle, MAGIC_CRYPTKEY, invalid_handle_error_code);
+}
That's not very nice. I'd suggest to always fail with ERROR_INVALID_PARAMETER. The few places that really need a different error code can handle it themselves.
On 2/17/21 18:24, Alexandre Julliard wrote:
Paul Gofman pgofman@codeweavers.com writes:
@@ -57,6 +57,37 @@ static HWND crypt_hWindow; #define CRYPT_Alloc(size) (LocalAlloc(LMEM_ZEROINIT, size)) #define CRYPT_Free(buffer) (LocalFree(buffer))
+static void *pointer_from_handle(UINT_PTR handle, DWORD magic, DWORD invalid_handle_error_code) +{
- if (!handle)
- {
SetLastError(invalid_handle_error_code);
return NULL;
- }
- if (*(DWORD *)handle != magic)
- {
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
- }
- return (void *)handle;
+}
+static PCRYPTPROV provider_from_handle(HCRYPTPROV handle, DWORD invalid_handle_error_code) +{
- return pointer_from_handle(handle, MAGIC_CRYPTPROV, invalid_handle_error_code);
+}
+static PCRYPTHASH hash_from_handle(HCRYPTHASH handle, DWORD invalid_handle_error_code) +{
- return pointer_from_handle(handle, MAGIC_CRYPTHASH, invalid_handle_error_code);
+}
+static PCRYPTKEY key_from_handle(HCRYPTKEY handle, DWORD invalid_handle_error_code) +{
- return pointer_from_handle(handle, MAGIC_CRYPTKEY, invalid_handle_error_code);
+}
That's not very nice. I'd suggest to always fail with ERROR_INVALID_PARAMETER. The few places that really need a different error code can handle it themselves.
I've tested all the cases when we are returning the _INVALID_HANDLE for crypt objects and it looks like it is always _INVALID_PARAMETER on Windows. I've updated the patches accordingly.
Fixes crash on start in "Re:ZERO -Starting Life in Another World- The Prophecy of the Throne".
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/advapi32/crypt.c | 15 +++++++++++++-- dlls/advapi32/tests/crypt.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/dlls/advapi32/crypt.c b/dlls/advapi32/crypt.c index 91da4034405..52ccc4f09cc 100644 --- a/dlls/advapi32/crypt.c +++ b/dlls/advapi32/crypt.c @@ -37,6 +37,7 @@ #include "winreg.h" #include "rpc.h" #include "wine/debug.h" +#include "wine/exception.h" #include "winternl.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt); @@ -64,11 +65,21 @@ static void *pointer_from_handle(UINT_PTR handle, DWORD magic, DWORD invalid_han SetLastError(invalid_handle_error_code); return NULL; } - if (*(DWORD *)handle != magic) + + __TRY { - SetLastError(ERROR_INVALID_PARAMETER); + if (*(DWORD *)handle != magic) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + } + __EXCEPT_PAGE_FAULT + { + SetLastError(invalid_handle_error_code); return NULL; } + __ENDTRY
return (void *)handle; } diff --git a/dlls/advapi32/tests/crypt.c b/dlls/advapi32/tests/crypt.c index 8d4f2ae5936..d9d6a97c681 100644 --- a/dlls/advapi32/tests/crypt.c +++ b/dlls/advapi32/tests/crypt.c @@ -154,6 +154,8 @@ static void test_CryptReleaseContext(void)
ret = CryptContextAddRef(0, NULL, 0); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError()); + ret = CryptContextAddRef(0xdeadbeef, NULL, 0); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
ret = CryptReleaseContext(prov, 0); ok(ret, "got %u\n", GetLastError()); @@ -272,11 +274,17 @@ static void test_incorrect_api_usage(void) ok (result, "%08x\n", GetLastError()); if (!result) return;
+ /* Looks like native handles are just pointers. */ + ok(!!*(void **)hProv, "Got zero *(void **)hProv.\n"); + result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash); ok (result, "%d\n", GetLastError()); if (!result) return; CryptDestroyHash(hHash);
+ result = CryptCreateHash(0xdeadbeef, CALG_SHA, 0, 0, &hHash); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptCreateHash(0, CALG_SHA, 0, 0, &hHash); ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
@@ -287,6 +295,29 @@ static void test_incorrect_api_usage(void) ok (result, "%d\n", GetLastError()); if (!result) return;
+ dwLen = 1; + result = CryptDecrypt(hKey, 0, TRUE, 0, &temp, &dwLen); + ok (result, "%d\n", GetLastError()); + result = CryptDecrypt(hKey, 0xdeadbeef, TRUE, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptDecrypt(0, 0, TRUE, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptDecrypt(0xdeadbeef, 0, TRUE, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + + result = CryptEncrypt(hKey, 0, TRUE, 0, &temp, &dwLen, sizeof(temp)); + ok (result, "%d\n", GetLastError()); + result = CryptEncrypt(hKey, 0xdeadbeef, TRUE, 0, &temp, &dwLen, sizeof(temp)); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptEncrypt(0, 0, TRUE, 0, &temp, &dwLen, sizeof(temp)); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptEncrypt(0xdeadbeef, 0, TRUE, 0, &temp, &dwLen, sizeof(temp)); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + + dwLen = 1; + result = CryptExportKey(hKey, 0xdeadbeef, 0, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptDestroyKey(hKey); ok (result, "%d\n", GetLastError());