Make crypt functions more robust in case of incorrect api usage.

This commit is contained in:
Michael Jung 2005-04-11 12:55:36 +00:00 committed by Alexandre Julliard
parent 962a5e7742
commit 44cb0906da
3 changed files with 220 additions and 40 deletions

View File

@ -178,6 +178,7 @@ PCRYPTPROV CRYPT_LoadProvider(PSTR pImage)
FIXME("Failed to load dll %s\n", debugstr_a(pImage)); FIXME("Failed to load dll %s\n", debugstr_a(pImage));
goto error; goto error;
} }
provider->dwMagic = MAGIC_CRYPTPROV;
provider->refcount = 1; provider->refcount = 1;
errorcode = NTE_PROVIDER_DLL_FAIL; errorcode = NTE_PROVIDER_DLL_FAIL;
@ -223,6 +224,7 @@ error:
SetLastError(errorcode); SetLastError(errorcode);
if (provider) if (provider)
{ {
provider->dwMagic = 0;
if (provider->hModule) if (provider->hModule)
FreeLibrary(provider->hModule); FreeLibrary(provider->hModule);
CRYPT_Free(provider->pVTable); 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, /* MSDN: When this flag is set, the value returned in phProv is undefined,
* and thus, the CryptReleaseContext function need not be called afterwards. * and thus, the CryptReleaseContext function need not be called afterwards.
* Therefore, we must clean up everything now. * Therefore, we must clean up everything now.
*/ */
if (dwFlags & CRYPT_DELETEKEYSET) if (dwFlags & CRYPT_DELETEKEYSET)
{ {
pProv->dwMagic = 0;
FreeLibrary(pProv->hModule); FreeLibrary(pProv->hModule);
CRYPT_Free(provname); CRYPT_Free(provname);
CRYPT_Free(pProv->pFuncs); CRYPT_Free(pProv->pFuncs);
@ -418,6 +421,7 @@ BOOL WINAPI CryptAcquireContextA (HCRYPTPROV *phProv, LPCSTR pszContainer,
error: error:
if (pProv) if (pProv)
{ {
pProv->dwMagic = 0;
if (pProv->hModule) if (pProv->hModule)
FreeLibrary(pProv->hModule); FreeLibrary(pProv->hModule);
if (pProv->pVTable) if (pProv->pVTable)
@ -494,6 +498,12 @@ BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFl
return FALSE; return FALSE;
} }
if (pProv->dwMagic != MAGIC_CRYPTPROV)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
pProv->refcount++; pProv->refcount++;
return TRUE; return TRUE;
} }
@ -524,10 +534,17 @@ BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags)
return FALSE; return FALSE;
} }
if (pProv->dwMagic != MAGIC_CRYPTPROV)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
pProv->refcount--; pProv->refcount--;
if (pProv->refcount <= 0) if (pProv->refcount <= 0)
{ {
ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags); ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags);
pProv->dwMagic = 0;
FreeLibrary(pProv->hModule); FreeLibrary(pProv->hModule);
#if 0 #if 0
CRYPT_Free(pProv->pVTable->pContextInfo); CRYPT_Free(pProv->pVTable->pContextInfo);
@ -566,6 +583,9 @@ BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
if (!hProv) if (!hProv)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
if (prov->dwMagic != MAGIC_CRYPTPROV)
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer); return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer);
} }
@ -599,7 +619,7 @@ BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey,
if (!prov) if (!prov)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
if (!phHash) if (!phHash || prov->dwMagic != MAGIC_CRYPTPROV)
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
if (dwFlags) if (dwFlags)
CRYPT_ReturnLastError(NTE_BAD_FLAGS); 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); 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); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
prov = key->pProvider; prov = key->pProvider;
@ -683,7 +703,7 @@ BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData
if (!prov || !hash) if (!prov || !hash)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
if (!phKey) if (!phKey || prov->dwMagic != MAGIC_CRYPTPROV)
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) )
CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
@ -724,6 +744,9 @@ BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash)
if (!hash) if (!hash)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
prov = hash->pProvider; prov = hash->pProvider;
ret = prov->pFuncs->pCPDestroyHash(prov->hPrivate, hash->hPrivate); ret = prov->pFuncs->pCPDestroyHash(prov->hPrivate, hash->hPrivate);
CRYPT_Free(hash); CRYPT_Free(hash);
@ -753,6 +776,9 @@ BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey)
if (!key) if (!key)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
if (!key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
prov = key->pProvider; prov = key->pProvider;
ret = prov->pFuncs->pCPDestroyKey(prov->hPrivate, key->hPrivate); ret = prov->pFuncs->pCPDestroyKey(prov->hPrivate, key->hPrivate);
CRYPT_Free(key); 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); TRACE("(0x%lx, %p, %08ld, %p)\n", hHash, pdwReserved, dwFlags, phHash);
orghash = (PCRYPTHASH)hHash; orghash = (PCRYPTHASH)hHash;
if (!orghash || pdwReserved || !phHash) if (!orghash || pdwReserved || !phHash || !orghash->pProvider ||
orghash->pProvider->dwMagic != MAGIC_CRYPTPROV)
{
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
}
prov = orghash->pProvider; prov = orghash->pProvider;
if (!prov->pFuncs->pCPDuplicateHash) 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); TRACE("(0x%lx, %p, %08ld, %p)\n", hKey, pdwReserved, dwFlags, phKey);
orgkey = (PCRYPTKEY)hKey; orgkey = (PCRYPTKEY)hKey;
if (!orgkey || pdwReserved || !phKey) if (!orgkey || pdwReserved || !phKey || !orgkey->pProvider ||
orgkey->pProvider->dwMagic != MAGIC_CRYPTPROV)
{
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
}
prov = orgkey->pProvider; prov = orgkey->pProvider;
if (!prov->pFuncs->pCPDuplicateKey) 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); 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); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
prov = key->pProvider; 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); 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); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
prov = key->pProvider; prov = key->pProvider;
@ -1152,7 +1184,7 @@ BOOL WINAPI CryptGenKey (HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKE
if (!prov) if (!prov)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
if (!phKey) if (!phKey || !prov || prov->dwMagic != MAGIC_CRYPTPROV)
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) )
CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); 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); 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); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
prov = hash->pProvider; 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); 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); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
prov = key->pProvider; 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); 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); 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) if (!prov)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
if (!phUserKey) if (!phUserKey || prov->dwMagic != MAGIC_CRYPTPROV)
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) )
CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
@ -1419,7 +1454,7 @@ BOOL WINAPI CryptHashData (HCRYPTHASH hHash, BYTE *pbData, DWORD dwDataLen, DWOR
if (!hash) if (!hash)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
if (!pbData || !dwDataLen) if (!pbData || !dwDataLen || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
prov = hash->pProvider; prov = hash->pProvider;
@ -1449,6 +1484,9 @@ BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags
if (!hash || !key) if (!hash || !key)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
prov = hash->pProvider; prov = hash->pProvider;
return prov->pFuncs->pCPHashSessionKey(prov->hPrivate, hash->hPrivate, key->hPrivate, dwFlags); 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); 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); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
if ( !(importkey = CRYPT_Alloc(sizeof(CRYPTKEY))) ) if ( !(importkey = CRYPT_Alloc(sizeof(CRYPTKEY))) )
@ -1527,7 +1565,7 @@ BOOL WINAPI CryptSignHashW (HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescript
if (!hash) if (!hash)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
if (!pdwSigLen) if (!pdwSigLen || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
prov = hash->pProvider; 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); 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); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
prov = hash->pProvider; 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); 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); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
prov = key->pProvider; prov = key->pProvider;
@ -1763,6 +1801,8 @@ BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DW
if (!prov) if (!prov)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
if (prov->dwMagic != MAGIC_CRYPTPROV)
CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
if (dwFlags & PP_USE_HARDWARE_RNG) if (dwFlags & PP_USE_HARDWARE_RNG)
{ {
FIXME("PP_USE_HARDWARE_RNG: What do I do with this?\n"); 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) if (!hash || !key)
CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); 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); CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
}
prov = hash->pProvider; prov = hash->pProvider;
return prov->pFuncs->pCPVerifySignature(prov->hPrivate, hash->hPrivate, pbSignature, dwSigLen, return prov->pFuncs->pCPVerifySignature(prov->hPrivate, hash->hPrivate, pbSignature, dwSigLen,
key->hPrivate, sDescription, dwFlags); key->hPrivate, sDescription, dwFlags);

View File

@ -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); BOOL (WINAPI *pCPVerifySignature)(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags);
} PROVFUNCS, *PPROVFUNCS; } PROVFUNCS, *PPROVFUNCS;
#define MAGIC_CRYPTPROV 0xA39E741F
typedef struct tagCRYPTPROV typedef struct tagCRYPTPROV
{ {
DWORD dwMagic;
UINT refcount; UINT refcount;
HMODULE hModule; HMODULE hModule;
PPROVFUNCS pFuncs; PPROVFUNCS pFuncs;

View File

@ -43,6 +43,28 @@ static BOOL (WINAPI *pCryptReleaseContext)(HCRYPTPROV, DWORD);
static BOOL (WINAPI *pCryptSetProviderExA)(LPCSTR, DWORD, DWORD*, DWORD); static BOOL (WINAPI *pCryptSetProviderExA)(LPCSTR, DWORD, DWORD*, DWORD);
static BOOL (WINAPI *pCryptCreateHash)(HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, HCRYPTHASH*); static BOOL (WINAPI *pCryptCreateHash)(HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, HCRYPTHASH*);
static BOOL (WINAPI *pCryptDestroyHash)(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) static void init_function_pointers(void)
{ {
@ -50,18 +72,39 @@ static void init_function_pointers(void)
if(hadvapi32) if(hadvapi32)
{ {
pCryptAcquireContextA = (void*)GetProcAddress(hadvapi32, "CryptAcquireContextA"); pCryptAcquireContextA = (void*)GetProcAddress(hadvapi32, "CryptAcquireContextA");
pCryptEnumProviderTypesA = (void*)GetProcAddress(hadvapi32, "CryptEnumProviderTypesA"); pCryptEnumProviderTypesA = (void*)GetProcAddress(hadvapi32, "CryptEnumProviderTypesA");
pCryptEnumProvidersA = (void*)GetProcAddress(hadvapi32, "CryptEnumProvidersA"); pCryptEnumProvidersA = (void*)GetProcAddress(hadvapi32, "CryptEnumProvidersA");
pCryptGetDefaultProviderA = (void*)GetProcAddress(hadvapi32, "CryptGetDefaultProviderA"); pCryptGetDefaultProviderA = (void*)GetProcAddress(hadvapi32, "CryptGetDefaultProviderA");
pCryptReleaseContext = (void*)GetProcAddress(hadvapi32, "CryptReleaseContext"); pCryptReleaseContext = (void*)GetProcAddress(hadvapi32, "CryptReleaseContext");
pCryptSetProviderExA = (void*)GetProcAddress(hadvapi32, "CryptSetProviderExA"); pCryptSetProviderExA = (void*)GetProcAddress(hadvapi32, "CryptSetProviderExA");
pCryptCreateHash = (void*)GetProcAddress(hadvapi32, "CryptCreateHash"); pCryptCreateHash = (void*)GetProcAddress(hadvapi32, "CryptCreateHash");
pCryptDestroyHash = (void*)GetProcAddress(hadvapi32, "CryptDestroyHash"); 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) static void init_environment(void)
{ {
HCRYPTPROV hProv; HCRYPTPROV hProv;
@ -161,15 +204,18 @@ static void test_incorrect_api_usage(void)
{ {
BOOL result; BOOL result;
HCRYPTPROV hProv, hProv2; 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. * "Uru - Ages beyond Myst Demo" installer as reported by Paul Vriens.
* *
* The installer destroys a hash object after having released the context * The installer destroys a hash object after having released the context
* with which the hash was created. This is not allowed according to MSDN, * with which the hash was created. This is not allowed according to MSDN,
* since CryptReleaseContext destroys all hash and key objects belonging to * 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. * 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()); ok (result, "%ld\n", GetLastError());
if (!result) return; 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, result = pCryptAcquireContextA(&hProv2, szBadKeySet, NULL, PROV_RSA_FULL,
CRYPT_DELETEKEYSET); CRYPT_DELETEKEYSET);
ok (result, "%ld\n", GetLastError()); ok (result, "%ld\n", GetLastError());
@ -191,15 +252,87 @@ static void test_incorrect_api_usage(void)
ok (result, "%ld\n", GetLastError()); ok (result, "%ld\n", GetLastError());
if (!result) return; if (!result) return;
/* We have to deactivate the next call for now, since it will crash wine. result = pCryptReleaseContext(hProv, 0);
*/ ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError());
#if 0
todo_wine { result = pCryptGenRandom(hProv, 1, &temp);
result = pCryptDestroyHash(hHash); ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError());
ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n",
GetLastError()); result = pCryptContextAddRef(hProv, NULL, 0);
} ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError());
#endif
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, static BOOL FindProvRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszProvName,