From 44cb0906da3dddbca1fe670e723b4d03aa3e2488 Mon Sep 17 00:00:00 2001 From: Michael Jung Date: Mon, 11 Apr 2005 12:55:36 +0000 Subject: [PATCH] Make crypt functions more robust in case of incorrect api usage. --- dlls/advapi32/crypt.c | 82 +++++++++++++---- dlls/advapi32/crypt.h | 3 + dlls/advapi32/tests/crypt.c | 175 +++++++++++++++++++++++++++++++----- 3 files changed, 220 insertions(+), 40 deletions(-) diff --git a/dlls/advapi32/crypt.c b/dlls/advapi32/crypt.c index 293261c334e..2b7a4fc9ed9 100644 --- a/dlls/advapi32/crypt.c +++ b/dlls/advapi32/crypt.c @@ -178,6 +178,7 @@ PCRYPTPROV CRYPT_LoadProvider(PSTR pImage) FIXME("Failed to load dll %s\n", debugstr_a(pImage)); goto error; } + provider->dwMagic = MAGIC_CRYPTPROV; provider->refcount = 1; errorcode = NTE_PROVIDER_DLL_FAIL; @@ -223,6 +224,7 @@ error: SetLastError(errorcode); if (provider) { + provider->dwMagic = 0; if (provider->hModule) FreeLibrary(provider->hModule); CRYPT_Free(provider->pVTable); @@ -400,9 +402,10 @@ BOOL WINAPI CryptAcquireContextA (HCRYPTPROV *phProv, LPCSTR pszContainer, /* MSDN: When this flag is set, the value returned in phProv is undefined, * and thus, the CryptReleaseContext function need not be called afterwards. * Therefore, we must clean up everything now. - */ + */ if (dwFlags & CRYPT_DELETEKEYSET) { + pProv->dwMagic = 0; FreeLibrary(pProv->hModule); CRYPT_Free(provname); CRYPT_Free(pProv->pFuncs); @@ -418,6 +421,7 @@ BOOL WINAPI CryptAcquireContextA (HCRYPTPROV *phProv, LPCSTR pszContainer, error: if (pProv) { + pProv->dwMagic = 0; if (pProv->hModule) FreeLibrary(pProv->hModule); if (pProv->pVTable) @@ -494,6 +498,12 @@ BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFl return FALSE; } + if (pProv->dwMagic != MAGIC_CRYPTPROV) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + pProv->refcount++; return TRUE; } @@ -524,10 +534,17 @@ BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags) return FALSE; } + if (pProv->dwMagic != MAGIC_CRYPTPROV) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + pProv->refcount--; if (pProv->refcount <= 0) { ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags); + pProv->dwMagic = 0; FreeLibrary(pProv->hModule); #if 0 CRYPT_Free(pProv->pVTable->pContextInfo); @@ -566,6 +583,9 @@ BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer) if (!hProv) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (prov->dwMagic != MAGIC_CRYPTPROV) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer); } @@ -599,7 +619,7 @@ BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, if (!prov) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); - if (!phHash) + if (!phHash || prov->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); if (dwFlags) CRYPT_ReturnLastError(NTE_BAD_FLAGS); @@ -648,7 +668,7 @@ BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, TRACE("(0x%lx, 0x%lx, %d, %08lx, %p, %p)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen); - if (!key || !pbData || !pdwDataLen) + if (!key || !pbData || !pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); prov = key->pProvider; @@ -683,7 +703,7 @@ BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData if (!prov || !hash) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); - if (!phKey) + if (!phKey || prov->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -724,6 +744,9 @@ BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash) if (!hash) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + prov = hash->pProvider; ret = prov->pFuncs->pCPDestroyHash(prov->hPrivate, hash->hPrivate); CRYPT_Free(hash); @@ -753,6 +776,9 @@ BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey) if (!key) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (!key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + prov = key->pProvider; ret = prov->pFuncs->pCPDestroyKey(prov->hPrivate, key->hPrivate); CRYPT_Free(key); @@ -783,8 +809,11 @@ BOOL WINAPI CryptDuplicateHash (HCRYPTHASH hHash, DWORD *pdwReserved, TRACE("(0x%lx, %p, %08ld, %p)\n", hHash, pdwReserved, dwFlags, phHash); orghash = (PCRYPTHASH)hHash; - if (!orghash || pdwReserved || !phHash) + if (!orghash || pdwReserved || !phHash || !orghash->pProvider || + orghash->pProvider->dwMagic != MAGIC_CRYPTPROV) + { CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + } prov = orghash->pProvider; if (!prov->pFuncs->pCPDuplicateHash) @@ -826,8 +855,11 @@ BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags TRACE("(0x%lx, %p, %08ld, %p)\n", hKey, pdwReserved, dwFlags, phKey); orgkey = (PCRYPTKEY)hKey; - if (!orgkey || pdwReserved || !phKey) + if (!orgkey || pdwReserved || !phKey || !orgkey->pProvider || + orgkey->pProvider->dwMagic != MAGIC_CRYPTPROV) + { CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + } prov = orgkey->pProvider; if (!prov->pFuncs->pCPDuplicateKey) @@ -878,7 +910,7 @@ BOOL WINAPI CryptEncrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, TRACE("(0x%lx, 0x%lx, %d, %08ld, %p, %p, %ld)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen); - if (!key || !pdwDataLen) + if (!key || !pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); prov = key->pProvider; @@ -1120,7 +1152,7 @@ BOOL WINAPI CryptExportKey (HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType, TRACE("(0x%lx, 0x%lx, %ld, %08ld, %p, %p)\n", hKey, hExpKey, dwBlobType, dwFlags, pbData, pdwDataLen); - if (!key || !pdwDataLen) + if (!key || !pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); prov = key->pProvider; @@ -1152,7 +1184,7 @@ BOOL WINAPI CryptGenKey (HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKE if (!prov) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); - if (!phKey) + if (!phKey || !prov || prov->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -1281,7 +1313,7 @@ BOOL WINAPI CryptGetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hHash, dwParam, pbData, pdwDataLen, dwFlags); - if (!hash || !pdwDataLen) + if (!hash || !pdwDataLen || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); prov = hash->pProvider; @@ -1316,7 +1348,7 @@ BOOL WINAPI CryptGetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hKey, dwParam, pbData, pdwDataLen, dwFlags); - if (!key || !pdwDataLen) + if (!key || !pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); prov = key->pProvider; @@ -1350,6 +1382,9 @@ BOOL WINAPI CryptGetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hProv, dwParam, pbData, pdwDataLen, dwFlags); + if (!prov || prov->dwMagic != MAGIC_CRYPTPROV) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + return prov->pFuncs->pCPGetProvParam(prov->hPrivate, dwParam, pbData, pdwDataLen, dwFlags); } @@ -1376,7 +1411,7 @@ BOOL WINAPI CryptGetUserKey (HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUse if (!prov) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); - if (!phUserKey) + if (!phUserKey || prov->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -1419,7 +1454,7 @@ BOOL WINAPI CryptHashData (HCRYPTHASH hHash, BYTE *pbData, DWORD dwDataLen, DWOR if (!hash) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); - if (!pbData || !dwDataLen) + if (!pbData || !dwDataLen || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); prov = hash->pProvider; @@ -1449,6 +1484,9 @@ BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags if (!hash || !key) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + prov = hash->pProvider; return prov->pFuncs->pCPHashSessionKey(prov->hPrivate, hash->hPrivate, key->hPrivate, dwFlags); } @@ -1476,7 +1514,7 @@ BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, BYTE *pbData, DWORD dwDataLen, TRACE("(0x%lx, %p, %ld, 0x%lx, %08ld, %p)\n", hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey); - if (!prov || !pbData || !dwDataLen || !phKey) + if (!prov || !pbData || !dwDataLen || !phKey || prov->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); if ( !(importkey = CRYPT_Alloc(sizeof(CRYPTKEY))) ) @@ -1527,7 +1565,7 @@ BOOL WINAPI CryptSignHashW (HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescript if (!hash) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); - if (!pdwSigLen) + if (!pdwSigLen || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); prov = hash->pProvider; @@ -1578,7 +1616,7 @@ BOOL WINAPI CryptSetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DW TRACE("(0x%lx, %ld, %p, %08ld)\n", hHash, dwParam, pbData, dwFlags); - if (!hash || !pbData) + if (!hash || !pbData || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); prov = hash->pProvider; @@ -1608,7 +1646,7 @@ BOOL WINAPI CryptSetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD TRACE("(0x%lx, %ld, %p, %08ld)\n", hKey, dwParam, pbData, dwFlags); - if (!key || !pbData) + if (!key || !pbData || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); prov = key->pProvider; @@ -1763,6 +1801,8 @@ BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DW if (!prov) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (prov->dwMagic != MAGIC_CRYPTPROV) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); if (dwFlags & PP_USE_HARDWARE_RNG) { FIXME("PP_USE_HARDWARE_RNG: What do I do with this?\n"); @@ -1818,9 +1858,13 @@ BOOL WINAPI CryptVerifySignatureW (HCRYPTHASH hHash, BYTE *pbSignature, DWORD dw if (!hash || !key) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); - if (!pbSignature || !dwSigLen) + if (!pbSignature || !dwSigLen || + !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV || + !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) + { CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); - + } + prov = hash->pProvider; return prov->pFuncs->pCPVerifySignature(prov->hPrivate, hash->hPrivate, pbSignature, dwSigLen, key->hPrivate, sDescription, dwFlags); diff --git a/dlls/advapi32/crypt.h b/dlls/advapi32/crypt.h index 4a56363b519..f5696e61dc1 100644 --- a/dlls/advapi32/crypt.h +++ b/dlls/advapi32/crypt.h @@ -56,8 +56,11 @@ typedef struct tagPROVFUNCS BOOL (WINAPI *pCPVerifySignature)(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags); } PROVFUNCS, *PPROVFUNCS; +#define MAGIC_CRYPTPROV 0xA39E741F + typedef struct tagCRYPTPROV { + DWORD dwMagic; UINT refcount; HMODULE hModule; PPROVFUNCS pFuncs; diff --git a/dlls/advapi32/tests/crypt.c b/dlls/advapi32/tests/crypt.c index 9fa28319ffd..77357aefd84 100644 --- a/dlls/advapi32/tests/crypt.c +++ b/dlls/advapi32/tests/crypt.c @@ -43,6 +43,28 @@ static BOOL (WINAPI *pCryptReleaseContext)(HCRYPTPROV, DWORD); static BOOL (WINAPI *pCryptSetProviderExA)(LPCSTR, DWORD, DWORD*, DWORD); static BOOL (WINAPI *pCryptCreateHash)(HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, HCRYPTHASH*); static BOOL (WINAPI *pCryptDestroyHash)(HCRYPTHASH); +static BOOL (WINAPI *pCryptGenRandom)(HCRYPTPROV, DWORD, BYTE*); +static BOOL (WINAPI *pCryptContextAddRef)(HCRYPTPROV, DWORD*, DWORD dwFlags); +static BOOL (WINAPI *pCryptGenKey)(HCRYPTPROV, ALG_ID, DWORD, HCRYPTKEY*); +static BOOL (WINAPI *pCryptDestroyKey)(HCRYPTKEY); +static BOOL (WINAPI *pCryptDecrypt)(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE*, DWORD*); +static BOOL (WINAPI *pCryptDeriveKey)(HCRYPTPROV, ALG_ID, HCRYPTHASH, DWORD, HCRYPTKEY*); +static BOOL (WINAPI *pCryptDuplicateHash)(HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*); +static BOOL (WINAPI *pCryptDuplicateKey)(HCRYPTKEY, DWORD*, DWORD, HCRYPTKEY*); +static BOOL (WINAPI *pCryptEncrypt)(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE*, DWORD*, DWORD); +static BOOL (WINAPI *pCryptExportKey)(HCRYPTKEY, HCRYPTKEY, DWORD, DWORD, BYTE*, DWORD*); +static BOOL (WINAPI *pCryptGetHashParam)(HCRYPTHASH, DWORD, BYTE*, DWORD*, DWORD); +static BOOL (WINAPI *pCryptGetKeyParam)(HCRYPTKEY, DWORD, BYTE*, DWORD*, DWORD); +static BOOL (WINAPI *pCryptGetProvParam)(HCRYPTPROV, DWORD, BYTE*, DWORD*, DWORD); +static BOOL (WINAPI *pCryptGetUserKey)(HCRYPTPROV, DWORD, HCRYPTKEY*); +static BOOL (WINAPI *pCryptHashData)(HCRYPTHASH, BYTE*, DWORD, DWORD); +static BOOL (WINAPI *pCryptHashSessionKey)(HCRYPTHASH, HCRYPTKEY, DWORD); +static BOOL (WINAPI *pCryptImportKey)(HCRYPTPROV, BYTE*, DWORD, HCRYPTKEY, DWORD, HCRYPTKEY*); +static BOOL (WINAPI *pCryptSignHashW)(HCRYPTHASH, DWORD, LPCWSTR, DWORD, BYTE*, DWORD*); +static BOOL (WINAPI *pCryptSetHashParam)(HCRYPTKEY, DWORD, BYTE*, DWORD); +static BOOL (WINAPI *pCryptSetKeyParam)(HCRYPTKEY, DWORD, BYTE*, DWORD); +static BOOL (WINAPI *pCryptSetProvParam)(HCRYPTPROV, DWORD, BYTE*, DWORD); +static BOOL (WINAPI *pCryptVerifySignatureW)(HCRYPTHASH, BYTE*, DWORD, HCRYPTKEY, LPCWSTR, DWORD); static void init_function_pointers(void) { @@ -50,18 +72,39 @@ static void init_function_pointers(void) if(hadvapi32) { - pCryptAcquireContextA = (void*)GetProcAddress(hadvapi32, "CryptAcquireContextA"); - pCryptEnumProviderTypesA = (void*)GetProcAddress(hadvapi32, "CryptEnumProviderTypesA"); - pCryptEnumProvidersA = (void*)GetProcAddress(hadvapi32, "CryptEnumProvidersA"); - pCryptGetDefaultProviderA = (void*)GetProcAddress(hadvapi32, "CryptGetDefaultProviderA"); - pCryptReleaseContext = (void*)GetProcAddress(hadvapi32, "CryptReleaseContext"); - pCryptSetProviderExA = (void*)GetProcAddress(hadvapi32, "CryptSetProviderExA"); - pCryptCreateHash = (void*)GetProcAddress(hadvapi32, "CryptCreateHash"); - pCryptDestroyHash = (void*)GetProcAddress(hadvapi32, "CryptDestroyHash"); + pCryptAcquireContextA = (void*)GetProcAddress(hadvapi32, "CryptAcquireContextA"); + pCryptEnumProviderTypesA = (void*)GetProcAddress(hadvapi32, "CryptEnumProviderTypesA"); + pCryptEnumProvidersA = (void*)GetProcAddress(hadvapi32, "CryptEnumProvidersA"); + pCryptGetDefaultProviderA = (void*)GetProcAddress(hadvapi32, "CryptGetDefaultProviderA"); + pCryptReleaseContext = (void*)GetProcAddress(hadvapi32, "CryptReleaseContext"); + pCryptSetProviderExA = (void*)GetProcAddress(hadvapi32, "CryptSetProviderExA"); + pCryptCreateHash = (void*)GetProcAddress(hadvapi32, "CryptCreateHash"); + pCryptDestroyHash = (void*)GetProcAddress(hadvapi32, "CryptDestroyHash"); + pCryptGenRandom = (void*)GetProcAddress(hadvapi32, "CryptGenRandom"); + pCryptContextAddRef = (void*)GetProcAddress(hadvapi32, "CryptContextAddRef"); + pCryptGenKey = (void*)GetProcAddress(hadvapi32, "CryptGenKey"); + pCryptDestroyKey = (void*)GetProcAddress(hadvapi32, "CryptDestroyKey"); + pCryptDecrypt = (void*)GetProcAddress(hadvapi32, "CryptDecrypt"); + pCryptDeriveKey = (void*)GetProcAddress(hadvapi32, "CryptDeriveKey"); + pCryptDuplicateHash = (void*)GetProcAddress(hadvapi32, "CryptDuplicateHash"); + pCryptDuplicateKey = (void*)GetProcAddress(hadvapi32, "CryptDuplicateKey"); + pCryptEncrypt = (void*)GetProcAddress(hadvapi32, "CryptEncrypt"); + pCryptExportKey = (void*)GetProcAddress(hadvapi32, "CryptExportKey"); + pCryptGetHashParam = (void*)GetProcAddress(hadvapi32, "CryptGetHashParam"); + pCryptGetKeyParam = (void*)GetProcAddress(hadvapi32, "CryptGetKeyParam"); + pCryptGetProvParam = (void*)GetProcAddress(hadvapi32, "CryptGetProvParam"); + pCryptGetUserKey = (void*)GetProcAddress(hadvapi32, "CryptGetUserKey"); + pCryptHashData = (void*)GetProcAddress(hadvapi32, "CryptHashData"); + pCryptHashSessionKey = (void*)GetProcAddress(hadvapi32, "CryptHashSessionKey"); + pCryptImportKey = (void*)GetProcAddress(hadvapi32, "CryptImportKey"); + pCryptSignHashW = (void*)GetProcAddress(hadvapi32, "CryptSignHashW"); + pCryptSetHashParam = (void*)GetProcAddress(hadvapi32, "CryptSetHashParam"); + pCryptSetKeyParam = (void*)GetProcAddress(hadvapi32, "CryptSetKeyParam"); + pCryptSetProvParam = (void*)GetProcAddress(hadvapi32, "CryptSetProvParam"); + pCryptVerifySignatureW = (void*)GetProcAddress(hadvapi32, "CryptVerifySignatureW"); } } - static void init_environment(void) { HCRYPTPROV hProv; @@ -161,15 +204,18 @@ static void test_incorrect_api_usage(void) { BOOL result; HCRYPTPROV hProv, hProv2; - HCRYPTHASH hHash; + HCRYPTHASH hHash, hHash2; + HCRYPTKEY hKey, hKey2; + BYTE temp; + DWORD dwLen, dwTemp; - /* This is to document a crash in wine due to incorrect api usage in the + /* This is to document incorrect api usage in the * "Uru - Ages beyond Myst Demo" installer as reported by Paul Vriens. * * The installer destroys a hash object after having released the context * with which the hash was created. This is not allowed according to MSDN, * since CryptReleaseContext destroys all hash and key objects belonging to - * the respective context. However, while wine crashes, Windows is more + * the respective context. However, while wine used to crash, Windows is more * robust here and returns an ERROR_INVALID_PARAMETER code. */ @@ -182,6 +228,21 @@ static void test_incorrect_api_usage(void) ok (result, "%ld\n", GetLastError()); if (!result) return; + result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey); + ok (result, "%ld\n", GetLastError()); + if (!result) return; + + result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2); + ok (result, "%ld\n", GetLastError()); + if (!result) return; + + result = pCryptDestroyKey(hKey2); + ok (result, "%ld\n", GetLastError()); + + dwTemp = CRYPT_MODE_ECB; + result = pCryptSetKeyParam(hKey2, KP_MODE, (BYTE*)&dwTemp, sizeof(DWORD)); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + result = pCryptAcquireContextA(&hProv2, szBadKeySet, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET); ok (result, "%ld\n", GetLastError()); @@ -191,15 +252,87 @@ static void test_incorrect_api_usage(void) ok (result, "%ld\n", GetLastError()); if (!result) return; - /* We have to deactivate the next call for now, since it will crash wine. - */ -#if 0 - todo_wine { - result = pCryptDestroyHash(hHash); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", - GetLastError()); - } -#endif + result = pCryptReleaseContext(hProv, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptGenRandom(hProv, 1, &temp); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptContextAddRef(hProv, NULL, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + dwLen = 1; + result = pCryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + dwLen = 1; + result = pCryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, &temp, &dwLen, 1); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptDuplicateHash(hHash, NULL, 0, &hHash2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptDuplicateKey(hKey, NULL, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + dwLen = 1; + result = pCryptExportKey(hKey, (HCRYPTPROV)NULL, 0, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + dwLen = 1; + result = pCryptGetHashParam(hHash, 0, &temp, &dwLen, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + dwLen = 1; + result = pCryptGetKeyParam(hKey, 0, &temp, &dwLen, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + dwLen = 1; + result = pCryptGetProvParam(hProv, 0, &temp, &dwLen, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptGetUserKey(hProv, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptHashData(hHash, &temp, 1, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptHashSessionKey(hHash, hKey, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptImportKey(hProv, &temp, 1, (HCRYPTKEY)NULL, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + dwLen = 1; + result = pCryptSignHashW(hHash, 0, NULL, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptSetKeyParam(hKey, 0, &temp, 1); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptSetHashParam(hHash, 0, &temp, 1); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptSetProvParam(hProv, 0, &temp, 1); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptVerifySignatureW(hHash, &temp, 1, hKey, NULL, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptDestroyHash(hHash); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptDestroyKey(hKey); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); } static BOOL FindProvRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszProvName,