/*
 * Unit tests for crypt functions
 *
 * Copyright (c) 2004 Michael Jung
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "winerror.h"
#include "winreg.h"

#include "wine/test.h"

static const char szRsaBaseProv[] = MS_DEF_PROV_A;
static const char szNonExistentProv[] = "Wine Nonexistent Cryptographic Provider v11.2";
static const char szKeySet[] = "wine_test_keyset";
static const char szBadKeySet[] = "wine_test_bad_keyset";
#define NON_DEF_PROV_TYPE 999

static BOOL (WINAPI *pCryptAcquireContextA)(HCRYPTPROV*,LPCSTR,LPCSTR,DWORD,DWORD);
static BOOL (WINAPI *pCryptEnumProviderTypesA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*);
static BOOL (WINAPI *pCryptEnumProvidersA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*);
static BOOL (WINAPI *pCryptGetDefaultProviderA)(DWORD, DWORD*, DWORD, LPSTR, DWORD*);
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 BOOLEAN (WINAPI *pSystemFunction036)(PVOID, ULONG);

static void init_function_pointers(void)
{
    HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");

    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");
    pSystemFunction036 = (void*)GetProcAddress(hadvapi32, "SystemFunction036");
}

static void init_environment(void)
{
	HCRYPTPROV hProv;
	
	/* Ensure that container "wine_test_keyset" does exist */
	if (!pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
	{
		pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_NEWKEYSET);
	}
	pCryptReleaseContext(hProv, 0);

	/* Ensure that container "wine_test_keyset" does exist in default PROV_RSA_FULL type provider */
	if (!pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))
	{
		pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET);
	}
	pCryptReleaseContext(hProv, 0);

	/* Ensure that container "wine_test_bad_keyset" does not exist. */
	if (pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
	{
		pCryptReleaseContext(hProv, 0);
		pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
	}
}

static void clean_up_environment(void)
{
	HCRYPTPROV hProv;

	/* Remove container "wine_test_keyset" */
	if (pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
	{
		pCryptReleaseContext(hProv, 0);
		pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
	}

	/* Remove container "wine_test_keyset" from default PROV_RSA_FULL type provider */
	if (pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))
	{
		pCryptReleaseContext(hProv, 0);
		pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
	}

        /* Remove container "wine_test_bad_keyset" */
        if (pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
        {
                pCryptReleaseContext(hProv, 0);
                pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
        }
}

static void test_acquire_context(void)
{
	BOOL result;
	HCRYPTPROV hProv;
	DWORD GLE;

	/* Provoke all kinds of error conditions (which are easy to provoke). 
	 * The order of the error tests seems to match Windows XP's rsaenh.dll CSP,
	 * but since this is likely to change between CSP versions, we don't check
	 * this. Please don't change the order of tests. */
	result = pCryptAcquireContextA(&hProv, NULL, NULL, 0, 0);
	ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError());
	
	result = pCryptAcquireContextA(&hProv, NULL, NULL, 1000, 0);
	ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError());

	result = pCryptAcquireContextA(&hProv, NULL, NULL, NON_DEF_PROV_TYPE, 0);
	ok(!result && GetLastError()==NTE_PROV_TYPE_NOT_DEF, "%d\n", GetLastError());
	
	result = pCryptAcquireContextA(&hProv, szKeySet, szNonExistentProv, PROV_RSA_FULL, 0);
	ok(!result && GetLastError()==NTE_KEYSET_NOT_DEF, "%d\n", GetLastError());

	result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, NON_DEF_PROV_TYPE, 0);
	ok(!result && GetLastError()==NTE_PROV_TYPE_NO_MATCH, "%d\n", GetLastError());
	
	/* This test fails under Win2k SP4:
	   result = TRUE, GetLastError() == ERROR_INVALID_PARAMETER
	SetLastError(0xdeadbeef);
	result = pCryptAcquireContextA(NULL, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
	ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d/%d\n", result, GetLastError());
	*/
	
	/* Last not least, try to really acquire a context. */
	hProv = 0;
	SetLastError(0xdeadbeef);
	result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
	GLE = GetLastError();
	ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND   || 
		      GLE == ERROR_SUCCESS            || 
		      GLE == ERROR_RING2_STACK_IN_USE || 
		      GLE == NTE_FAIL                 ||
		      GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GLE);

	if (hProv) 
		pCryptReleaseContext(hProv, 0);

	/* Try again, witch an empty ("\0") szProvider parameter */
	hProv = 0;
	SetLastError(0xdeadbeef);
	result = pCryptAcquireContextA(&hProv, szKeySet, "", PROV_RSA_FULL, 0);
	GLE = GetLastError();
	ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND   || 
		      GLE == ERROR_SUCCESS            || 
		      GLE == ERROR_RING2_STACK_IN_USE || 
		      GLE == NTE_FAIL                 ||
		      GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GetLastError());

	if (hProv) 
		pCryptReleaseContext(hProv, 0);
}

static void test_incorrect_api_usage(void)
{
    BOOL result;
    HCRYPTPROV hProv, hProv2;
    HCRYPTHASH hHash, hHash2;
    HCRYPTKEY hKey, hKey2;
    BYTE temp;
    DWORD dwLen, dwTemp;

    /* 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 used to crash, Windows is more 
     * robust here and returns an ERROR_INVALID_PARAMETER code.
     */
    
    result = pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, 
                                   PROV_RSA_FULL, CRYPT_NEWKEYSET);
    ok (result, "%08x\n", GetLastError());
    if (!result) return;

    result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
    ok (result, "%d\n", GetLastError());
    if (!result) return;
    pCryptDestroyHash(hHash);

    result = pCryptCreateHash(0, CALG_SHA, 0, 0, &hHash);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    result = pCryptGenKey(0, CALG_RC4, 0, &hKey);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey);
    ok (result, "%d\n", GetLastError());
    if (!result) return;

    result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
    ok (result, "%d\n", GetLastError());
    if (!result) return;

    result = pCryptDestroyKey(hKey2);
    ok (result, "%d\n", GetLastError());

    dwTemp = CRYPT_MODE_ECB;    
    result = pCryptSetKeyParam(hKey2, KP_MODE, (BYTE*)&dwTemp, sizeof(DWORD));
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
    
    result = pCryptAcquireContextA(&hProv2, szBadKeySet, NULL, PROV_RSA_FULL, 
                                   CRYPT_DELETEKEYSET);
    ok (result, "%d\n", GetLastError());
    if (!result) return;
    
    result = pCryptReleaseContext(hProv, 0);
    ok (result, "%d\n", GetLastError());
    if (!result) return;

    result = pCryptReleaseContext(hProv, 0);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    result = pCryptGenRandom(hProv, 1, &temp);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

#ifdef CRASHES_ON_NT40
    result = pCryptContextAddRef(hProv, NULL, 0);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
#endif

    result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    dwLen = 1;
    result = pCryptDecrypt(hKey, 0, TRUE, 0, &temp, &dwLen);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    dwLen = 1;
    result = pCryptEncrypt(hKey, 0, TRUE, 0, &temp, &dwLen, 1);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    result = pCryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey2);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

#ifdef CRASHES_ON_NT40
    result = pCryptDuplicateHash(hHash, NULL, 0, &hHash2);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    result = pCryptDuplicateKey(hKey, NULL, 0, &hKey2);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
#endif

    dwLen = 1;
    result = pCryptExportKey(hKey, 0, 0, 0, &temp, &dwLen);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    dwLen = 1;
    result = pCryptGetHashParam(hHash, 0, &temp, &dwLen, 0);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    dwLen = 1;
    result = pCryptGetKeyParam(hKey, 0, &temp, &dwLen, 0);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    dwLen = 1;
    result = pCryptGetProvParam(hProv, 0, &temp, &dwLen, 0);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
    
    result = pCryptGetUserKey(hProv, 0, &hKey2);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    result = pCryptHashData(hHash, &temp, 1, 0);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    result = pCryptHashSessionKey(hHash, hKey, 0);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    result = pCryptImportKey(hProv, &temp, 1, 0, 0, &hKey2);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    if (pCryptSignHashW)
    {
        dwLen = 1;
        result = pCryptSignHashW(hHash, 0, NULL, 0, &temp, &dwLen);
        ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
            GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
    }
    else
        win_skip("CryptSignHashW is not available\n");

    result = pCryptSetKeyParam(hKey, 0, &temp, 1);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    result = pCryptSetHashParam(hHash, 0, &temp, 1);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    result = pCryptSetProvParam(hProv, 0, &temp, 1);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());

    if (pCryptVerifySignatureW)
    {
        result = pCryptVerifySignatureW(hHash, &temp, 1, hKey, NULL, 0);
        ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
            GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
    }
    else
        win_skip("CryptVerifySignatureW is not available\n");

    result = pCryptDestroyHash(hHash);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
    
    result = pCryptDestroyKey(hKey);
    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
}

static const BYTE privKey[] = {
 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };

static void test_verify_sig(void)
{
	BOOL ret;
	HCRYPTPROV prov;
	HCRYPTKEY key;
	HCRYPTHASH hash;
	BYTE bogus[] = { 0 };

	if (!pCryptVerifySignatureW)
	{
		win_skip("CryptVerifySignatureW is not available\n");
		return;
	}

	SetLastError(0xdeadbeef);
	ret = pCryptVerifySignatureW(0, NULL, 0, 0, NULL, 0);
	if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
	{
		win_skip("CryptVerifySignatureW is not implemented\n");
		return;
	}
	ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
	 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
	ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL,
	 CRYPT_NEWKEYSET);
	if (!ret && GetLastError() == NTE_EXISTS)
		ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL, 0);
	ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
	ret = pCryptImportKey(prov, (LPBYTE)privKey, sizeof(privKey), 0, 0, &key);
	ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
	ret = pCryptCreateHash(prov, CALG_MD5, 0, 0, &hash);
	ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
	SetLastError(0xdeadbeef);
	ret = pCryptVerifySignatureW(hash, NULL, 0, 0, NULL, 0);
	ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
	 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
	SetLastError(0xdeadbeef);
	ret = pCryptVerifySignatureW(0, NULL, 0, key, NULL, 0);
	ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
	 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
	SetLastError(0xdeadbeef);
	ret = pCryptVerifySignatureW(hash, NULL, 0, key, NULL, 0);
	ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
	 GetLastError() == ERROR_INVALID_PARAMETER),
	 "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
	 GetLastError());
	SetLastError(0xdeadbeef);
	ret = pCryptVerifySignatureW(hash, NULL, sizeof(bogus), key, NULL, 0);
	ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
	 GetLastError() == ERROR_INVALID_PARAMETER),
	 "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
	 GetLastError());
	SetLastError(0xdeadbeef);
	ret = pCryptVerifySignatureW(hash, bogus, 0, key, NULL, 0);
	ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
	 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
	SetLastError(0xdeadbeef);
	ret = pCryptVerifySignatureW(hash, bogus, sizeof(bogus), key, NULL, 0);
	ok(!ret &&
         (GetLastError() == NTE_BAD_SIGNATURE ||
         broken(GetLastError() == NTE_BAD_HASH_STATE /* older NT4 */)),
	 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
	pCryptDestroyKey(key);
	pCryptDestroyHash(hash);
	pCryptReleaseContext(prov, 0);
}

static BOOL FindProvRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszProvName, 
			    DWORD *pcbProvName, DWORD *pdwProvCount)
{
	HKEY hKey;
	HKEY subkey;
	DWORD size = sizeof(DWORD);
	
	if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider", &hKey))
		return FALSE;
	
	RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwProvCount, pcbProvName, 
				 NULL, NULL, NULL, NULL, NULL, NULL);
	(*pcbProvName)++;

	if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))
		return FALSE;
	
	RegEnumKeyEx(hKey, dwIndex, *pszProvName, pcbProvName, NULL, NULL, NULL, NULL);
	(*pcbProvName)++;

	RegOpenKey(hKey, *pszProvName, &subkey);
	RegQueryValueEx(subkey, "Type", NULL, NULL, (LPBYTE)pdwProvType, &size);
	
	RegCloseKey(subkey);
	RegCloseKey(hKey);
	
	return TRUE;
}

static void test_enum_providers(void)
{
	/* expected results */
	CHAR *pszProvName = NULL;
	DWORD cbName;
	DWORD dwType;
	DWORD provCount;
	DWORD dwIndex = 0;
	
	/* actual results */
	CHAR *provider = NULL;
	DWORD providerLen;
	DWORD type;
	DWORD count;
	DWORD result;
	DWORD notNull = 5;
	DWORD notZeroFlags = 5;
	
	if(!pCryptEnumProvidersA)
	{
	    win_skip("CryptEnumProvidersA is not available\n");
	    return;
	}
	
	if (!FindProvRegVals(dwIndex, &dwType, &pszProvName, &cbName, &provCount))
	{
	    win_skip("Could not find providers in registry\n");
	    return;
	}
	
	/* check pdwReserved flag for NULL */
	result = pCryptEnumProvidersA(dwIndex, &notNull, 0, &type, NULL, &providerLen);
	ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
	
	/* check dwFlags == 0 */
	result = pCryptEnumProvidersA(dwIndex, NULL, notZeroFlags, &type, NULL, &providerLen);
	ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d\n", GetLastError());
	
	/* alloc provider to half the size required
	 * cbName holds the size required */
	providerLen = cbName / 2;
	if (!(provider = LocalAlloc(LMEM_ZEROINIT, providerLen)))
		return;

	result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
	ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
		ERROR_MORE_DATA, GetLastError());

	LocalFree(provider);

	/* loop through the providers to get the number of providers 
	 * after loop ends, count should be provCount + 1 so subtract 1
	 * to get actual number of providers */
	count = 0;
	while(pCryptEnumProvidersA(count++, NULL, 0, &type, NULL, &providerLen))
		;
	count--;
	ok(count==provCount, "expected %i, got %i\n", (int)provCount, (int)count);
	
	/* loop past the actual number of providers to get the error
	 * ERROR_NO_MORE_ITEMS */
	for (count = 0; count < provCount + 1; count++)
		result = pCryptEnumProvidersA(count, NULL, 0, &type, NULL, &providerLen);
	ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %d\n", 
			ERROR_NO_MORE_ITEMS, GetLastError());
	
	/* check expected versus actual values returned */
	result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, NULL, &providerLen);
	ok(result && providerLen==cbName, "expected %i, got %i\n", (int)cbName, (int)providerLen);
	if (!(provider = LocalAlloc(LMEM_ZEROINIT, providerLen)))
		return;
		
	providerLen = -1;
	result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
	ok(result, "expected TRUE, got %d\n", result);
	ok(type==dwType, "expected %d, got %d\n", dwType, type);
	if (pszProvName)
	    ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
	ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);

	providerLen = -1000;
	provider[0] = 0;
	result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
	ok(result, "expected TRUE, got %d\n", result);
	ok(type==dwType, "expected %d, got %d\n", dwType, type);
	if (pszProvName)
	    ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
	ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);

	LocalFree(pszProvName);
	LocalFree(provider);
}

static BOOL FindProvTypesRegVals(DWORD *pdwIndex, DWORD *pdwProvType, LPSTR *pszTypeName,
				 DWORD *pcbTypeName, DWORD *pdwTypeCount)
{
	HKEY hKey;
	HKEY hSubKey;
	PSTR ch;
	LPSTR szName;
	DWORD cbName;
	BOOL ret = FALSE;

	if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey))
		return FALSE;

	if (RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwTypeCount, &cbName, NULL,
			NULL, NULL, NULL, NULL, NULL))
		goto cleanup;
	cbName++;

	if (!(szName = LocalAlloc(LMEM_ZEROINIT, cbName)))
		goto cleanup;

	while (!RegEnumKeyEx(hKey, *pdwIndex, szName, &cbName, NULL, NULL, NULL, NULL))
	{
		cbName++;
		ch = szName + strlen(szName);
		/* Convert "Type 000" to 0, etc/ */
		*pdwProvType = *(--ch) - '0';
		*pdwProvType += (*(--ch) - '0') * 10;
		*pdwProvType += (*(--ch) - '0') * 100;

		if (RegOpenKey(hKey, szName, &hSubKey))
			break;

		if (!RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, NULL, pcbTypeName))
		{
			if (!(*pszTypeName = LocalAlloc(LMEM_ZEROINIT, *pcbTypeName)))
				break;

			if (!RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, (LPBYTE)*pszTypeName, pcbTypeName))
			{
				ret = TRUE;
				break;
			}

			LocalFree(*pszTypeName);
		}

		RegCloseKey(hSubKey);

		(*pdwIndex)++;
	}
	RegCloseKey(hSubKey);
	LocalFree(szName);

cleanup:
	RegCloseKey(hKey);

	return ret;
}

static void test_enum_provider_types(void)
{
	/* expected values */
	DWORD dwProvType = 0;
	LPSTR pszTypeName = NULL;
	DWORD cbTypeName;
	DWORD dwTypeCount;

	/* actual values */
	DWORD index = 0;
	DWORD provType;
	LPSTR typeName = NULL;
	DWORD typeNameSize;
	DWORD typeCount;
	DWORD result;
	DWORD notNull = 5;
	DWORD notZeroFlags = 5;

	if(!pCryptEnumProviderTypesA)
	{
		win_skip("CryptEnumProviderTypesA is not available\n");
		return;
	}

	if (!FindProvTypesRegVals(&index, &dwProvType, &pszTypeName, &cbTypeName, &dwTypeCount))
	{
		skip("Could not find provider types in registry\n");
		return;
	}

	/* check pdwReserved for NULL */
	result = pCryptEnumProviderTypesA(index, &notNull, 0, &provType, typeName, &typeNameSize);
	ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n",
		GetLastError());

	/* check dwFlags == zero */
	result = pCryptEnumProviderTypesA(index, NULL, notZeroFlags, &provType, typeName, &typeNameSize);
	ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected ERROR_INVALID_PARAMETER, got %d\n",
		GetLastError());

	/* This test fails under Win2k SP4:
	 * result = TRUE, GetLastError() == 0xdeadbeef */
	if (0)
	{
		/* alloc provider type to half the size required
		 * cbTypeName holds the size required */
		typeNameSize = cbTypeName / 2;
		if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize)))
			goto cleanup;

		SetLastError(0xdeadbeef);
		result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
		ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %d/%d\n",
			result, GetLastError());

		LocalFree(typeName);
	}

	/* loop through the provider types to get the number of provider types 
	 * after loop ends, count should be dwTypeCount + 1 so subtract 1
	 * to get actual number of provider types */
	typeCount = 0;
	while(pCryptEnumProviderTypesA(typeCount++, NULL, 0, &provType, NULL, &typeNameSize))
		;
	typeCount--;
	ok(typeCount==dwTypeCount, "expected %d, got %d\n", dwTypeCount, typeCount);

	/* loop past the actual number of provider types to get the error
	 * ERROR_NO_MORE_ITEMS */
	for (typeCount = 0; typeCount < dwTypeCount + 1; typeCount++)
		result = pCryptEnumProviderTypesA(typeCount, NULL, 0, &provType, NULL, &typeNameSize);
	ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n",
		GetLastError());

	/* check expected versus actual values returned */
	result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, NULL, &typeNameSize);
	ok(result && typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
	if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize)))
		goto cleanup;

	typeNameSize = 0xdeadbeef;
	result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
	ok(result, "expected TRUE, got %d\n", result);
	ok(provType==dwProvType, "expected %d, got %d\n", dwProvType, provType);
	if (pszTypeName)
		ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName, typeName);
	ok(typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);

	LocalFree(typeName);
cleanup:
	LocalFree(pszTypeName);
}

static BOOL FindDfltProvRegVals(DWORD dwProvType, DWORD dwFlags, LPSTR *pszProvName, DWORD *pcbProvName)
{
	HKEY hKey;
	PSTR keyname;
	PSTR ptr;
	DWORD user = dwFlags & CRYPT_USER_DEFAULT;
	
	LPCSTR machinestr = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
	LPCSTR userstr = "Software\\Microsoft\\Cryptography\\Provider Type XXX";
	
	keyname = LocalAlloc(LMEM_ZEROINIT, (user ? strlen(userstr) : strlen(machinestr)) + 1);
	if (keyname)
	{
		user ? strcpy(keyname, userstr) : strcpy(keyname, machinestr);
		ptr = keyname + strlen(keyname);
		*(--ptr) = (dwProvType % 10) + '0';
		*(--ptr) = ((dwProvType / 10) % 10) + '0';
		*(--ptr) = (dwProvType / 100) + '0';
	} else
		return FALSE;
	
	if (RegOpenKey((dwFlags & CRYPT_USER_DEFAULT) ?  HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey))
	{
		LocalFree(keyname);
		return FALSE;
	}
	LocalFree(keyname);
	
	if (RegQueryValueEx(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
	{
		if (GetLastError() != ERROR_MORE_DATA)
			SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
		return FALSE;
	}
	
	if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))
		return FALSE;
	
	if (RegQueryValueEx(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
	{
		if (GetLastError() != ERROR_MORE_DATA)
			SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
		return FALSE;
	}
	
	RegCloseKey(hKey);
	
	return TRUE;
}

static void test_get_default_provider(void)
{
	/* expected results */
	DWORD dwProvType = PROV_RSA_FULL;
	DWORD dwFlags = CRYPT_MACHINE_DEFAULT;
	LPSTR pszProvName = NULL;
	DWORD cbProvName;
	
	/* actual results */
	DWORD provType = PROV_RSA_FULL;
	DWORD flags = CRYPT_MACHINE_DEFAULT;
	LPSTR provName = NULL;
	DWORD provNameSize;
	DWORD result;
	DWORD notNull = 5;
	
	if(!pCryptGetDefaultProviderA)
	{
	    win_skip("CryptGetDefaultProviderA is not available\n");
	    return;
	}
	
	if(!FindDfltProvRegVals(dwProvType, dwFlags, &pszProvName, &cbProvName))
	{
	    skip("Could not find default provider in registry\n");
	    return;
	}
	
	/* check pdwReserved for NULL */
	result = pCryptGetDefaultProviderA(provType, &notNull, flags, provName, &provNameSize);
	ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
		ERROR_INVALID_PARAMETER, GetLastError());
	
	/* check for invalid flag */
	flags = 0xdeadbeef;
	result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
	ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %d, got %d\n",
		NTE_BAD_FLAGS, GetLastError());
	flags = CRYPT_MACHINE_DEFAULT;
	
	/* check for invalid prov type */
	provType = 0xdeadbeef;
	result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
	ok(!result && (GetLastError() == NTE_BAD_PROV_TYPE ||
	               GetLastError() == ERROR_INVALID_PARAMETER),
		"expected NTE_BAD_PROV_TYPE or ERROR_INVALID_PARAMETER, got %d/%d\n",
		result, GetLastError());
	provType = PROV_RSA_FULL;
	
	SetLastError(0);
	
	/* alloc provName to half the size required
	 * cbProvName holds the size required */
	provNameSize = cbProvName / 2;
	if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
		return;
	
	result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
	ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
		ERROR_MORE_DATA, GetLastError());
		
	LocalFree(provName);
	
	/* check expected versus actual values returned */
	result = pCryptGetDefaultProviderA(provType, NULL, flags, NULL, &provNameSize);
	ok(result && provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
	provNameSize = cbProvName;
	
	if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
		return;
	
	provNameSize = 0xdeadbeef;
	result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
	ok(result, "expected TRUE, got %d\n", result);
	if(pszProvName)
	    ok(!strcmp(pszProvName, provName), "expected %s, got %s\n", pszProvName, provName);
	ok(provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);

	LocalFree(pszProvName);
	LocalFree(provName);
}

static void test_set_provider_ex(void)
{
	DWORD result;
	DWORD notNull = 5;
        LPSTR curProvName = NULL;
        DWORD curlen;
	
	/* results */
	LPSTR pszProvName = NULL;
	DWORD cbProvName;
	
	if(!pCryptGetDefaultProviderA || !pCryptSetProviderExA)
	{
	    win_skip("CryptGetDefaultProviderA and/or CryptSetProviderExA are not available\n");
	    return;
	}

        /* store the current one */
        pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &curlen);
        if (!(curProvName = LocalAlloc(LMEM_ZEROINIT, curlen)))
            return;
        result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, curProvName, &curlen);
        ok(result, "%d\n", GetLastError());

	/* check pdwReserved for NULL */
	result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, &notNull, CRYPT_MACHINE_DEFAULT);
	ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
		ERROR_INVALID_PARAMETER, GetLastError());

	/* remove the default provider and then set it to MS_DEF_PROV/PROV_RSA_FULL */
        SetLastError(0xdeadbeef);
	result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT | CRYPT_DELETE_DEFAULT);
	if (!result)
	{
                ok( GetLastError() == ERROR_ACCESS_DENIED || broken(GetLastError() == ERROR_INVALID_PARAMETER),
                    "wrong error %u\n", GetLastError() );
		skip("Not enough rights to remove the default provider\n");
                LocalFree(curProvName);
		return;
	}

	result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
	ok(result, "%d\n", GetLastError());
	
	/* call CryptGetDefaultProvider to see if they match */
	result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &cbProvName);
	ok(result, "%d\n", GetLastError());
	if (!(pszProvName = LocalAlloc(LMEM_ZEROINIT, cbProvName)))
		goto reset;

	result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, pszProvName, &cbProvName);
	ok(result && !strcmp(MS_DEF_PROV, pszProvName), "expected %s, got %s\n", MS_DEF_PROV, pszProvName);
	ok(result && cbProvName==(strlen(MS_DEF_PROV) + 1), "expected %i, got %d\n", (lstrlenA(MS_DEF_PROV) + 1), cbProvName);

	LocalFree(pszProvName);

reset:
        /* Set the provider back to it's original */
        result = pCryptSetProviderExA(curProvName, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
        ok(result, "%d\n", GetLastError());
        LocalFree(curProvName);
}

static void test_machine_guid(void)
{
   char originalGuid[40];
   LONG r;
   HKEY key;
   DWORD size;
   HCRYPTPROV hCryptProv;
   BOOL restoreGuid = FALSE, ret;

   r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography",
                     0, KEY_ALL_ACCESS, &key);
   if (r != ERROR_SUCCESS)
   {
       skip("couldn't open HKLM\\Software\\Microsoft\\Cryptography\n");
       return;
   }
   /* Cache existing MachineGuid, and delete it */
   size = sizeof(originalGuid);
   r = RegQueryValueExA(key, "MachineGuid", NULL, NULL, (BYTE *)originalGuid,
                        &size);
   if (r == ERROR_SUCCESS)
   {
       restoreGuid = TRUE;
       r = RegDeleteValueA(key, "MachineGuid");
       ok(!r, "RegDeleteValueA failed: %d\n", r);
   }
   else
       ok(r == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n",
          r);
   /* Create and release a provider */
   ret = pCryptAcquireContextA(&hCryptProv, szKeySet, NULL, PROV_RSA_FULL, 0);
   ok(ret || broken(!ret && GetLastError() == NTE_KEYSET_ENTRY_BAD /* NT4 */),
      "CryptAcquireContextA failed: %08x\n", GetLastError());
   pCryptReleaseContext(hCryptProv, 0);

   if (restoreGuid)
       RegSetValueExA(key, "MachineGuid", 0, REG_SZ, (const BYTE *)originalGuid,
                      strlen(originalGuid)+1);
   RegCloseKey(key);
}

#define key_length 16

static const unsigned char key[key_length] =
    { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd,
      0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 };

static void test_rc2_keylen(void)
{
    struct KeyBlob
    {
        BLOBHEADER header;
        DWORD key_size;
        BYTE key_data[2048];
    } key_blob;

    HCRYPTPROV provider;
    HCRYPTKEY hkey = 0;
    BOOL ret;

    SetLastError(0xdeadbeef);
    ret = pCryptAcquireContextA(&provider, NULL, NULL,
                                PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    ok(ret, "CryptAcquireContext error %u\n", GetLastError());
    if (ret)
    {
        key_blob.header.bType = PLAINTEXTKEYBLOB;
        key_blob.header.bVersion = CUR_BLOB_VERSION;
        key_blob.header.reserved = 0;
        key_blob.header.aiKeyAlg = CALG_RC2;
        key_blob.key_size = sizeof(key);
        memcpy(key_blob.key_data, key, key_length);

        /* Importing a 16-byte key works with the default provider. */
        SetLastError(0xdeadbeef);
        ret = pCryptImportKey(provider, (BYTE*)&key_blob,
                          sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
                          0, CRYPT_IPSEC_HMAC_KEY, &hkey);
        /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
        ok(ret ||
           broken(!ret && GetLastError() == NTE_BAD_FLAGS),
           "CryptImportKey error %08x\n", GetLastError());

        if (ret)
            pCryptDestroyKey(hkey);
        pCryptReleaseContext(provider, 0);
    }

    SetLastError(0xdeadbeef);
    ret = pCryptAcquireContextA(&provider, NULL, MS_DEF_PROV,
                                PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    ok(ret, "CryptAcquireContext error %08x\n", GetLastError());

    if (ret)
    {
        /* Importing a 16-byte key doesn't work with the base provider.. */
        SetLastError(0xdeadbeef);
        ret = pCryptImportKey(provider, (BYTE*)&key_blob,
                              sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
                              0, 0, &hkey);
        ok(!ret && (GetLastError() == NTE_BAD_DATA ||
                    GetLastError() == NTE_BAD_LEN || /* Win7 */
                    GetLastError() == NTE_BAD_TYPE || /* W2K */
                    GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */
           "unexpected error %08x\n", GetLastError());
        /* but importing an 56-bit (7-byte) key does.. */
        key_blob.key_size = 7;
        SetLastError(0xdeadbeef);
        ret = pCryptImportKey(provider, (BYTE*)&key_blob,
                              sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
                              0, 0, &hkey);
        ok(ret ||
           broken(!ret && GetLastError() == NTE_BAD_TYPE) || /* W2K */
           broken(!ret && GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */
           "CryptAcquireContext error %08x\n", GetLastError());
        if (ret)
            pCryptDestroyKey(hkey);
        /* as does importing a 16-byte key with the base provider when
         * CRYPT_IPSEC_HMAC_KEY is specified.
         */
        key_blob.key_size = sizeof(key);
        SetLastError(0xdeadbeef);
        ret = pCryptImportKey(provider, (BYTE*)&key_blob,
                              sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
                              0, CRYPT_IPSEC_HMAC_KEY, &hkey);
        /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
        ok(ret ||
           broken(!ret && GetLastError() == NTE_BAD_FLAGS),
           "CryptImportKey error %08x\n", GetLastError());
        if (ret)
            pCryptDestroyKey(hkey);

        pCryptReleaseContext(provider, 0);
    }

    key_blob.key_size = sizeof(key);
    SetLastError(0xdeadbeef);
    ret = pCryptAcquireContextA(&provider, NULL, NULL,
                                PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    ok(ret, "CryptAcquireContext error %08x\n", GetLastError());

    if (ret)
    {
        /* Importing a 16-byte key also works with the default provider when
         * CRYPT_IPSEC_HMAC_KEY is specified.
         */
        SetLastError(0xdeadbeef);
        ret = pCryptImportKey(provider, (BYTE*)&key_blob,
                              sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
                              0, CRYPT_IPSEC_HMAC_KEY, &hkey);
        ok(ret ||
           broken(!ret && GetLastError() == NTE_BAD_FLAGS),
           "CryptImportKey error %08x\n", GetLastError());
        if (ret)
            pCryptDestroyKey(hkey);

        /* There is no apparent limit to the size of the input key when
         * CRYPT_IPSEC_HMAC_KEY is specified.
         */
        key_blob.key_size = sizeof(key_blob.key_data);
        SetLastError(0xdeadbeef);
        ret = pCryptImportKey(provider, (BYTE*)&key_blob,
                              sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
                              0, CRYPT_IPSEC_HMAC_KEY, &hkey);
        ok(ret ||
           broken(!ret && GetLastError() == NTE_BAD_FLAGS),
           "CryptImportKey error %08x\n", GetLastError());
        if (ret)
            pCryptDestroyKey(hkey);

        pCryptReleaseContext(provider, 0);
    }
}

static void test_SystemFunction036(void)
{
    BOOL ret;
    int test;

    if (!pSystemFunction036)
    {
        win_skip("SystemFunction036 is not available\n");
        return;
    }

    ret = pSystemFunction036(NULL, 0);
    ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);

    /* Test crashes on Windows. */
    if (0)
    {
        SetLastError(0xdeadbeef);
        ret = pSystemFunction036(NULL, 5);
        trace("ret = %d, GetLastError() = %d\n", ret, GetLastError());
    }

    ret = pSystemFunction036(&test, 0);
    ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);

    ret = pSystemFunction036(&test, sizeof(int));
    ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
}

START_TEST(crypt)
{
    init_function_pointers();
    if (pCryptAcquireContextA && pCryptReleaseContext)
    {
	test_rc2_keylen();
	init_environment();
	test_acquire_context();
	test_incorrect_api_usage();
	test_verify_sig();
	test_machine_guid();
	clean_up_environment();
    }
	
	test_enum_providers();
	test_enum_provider_types();
	test_get_default_provider();
	test_set_provider_ex();
	test_SystemFunction036();
}
