1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Unit tests for crypt functions
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright (c) 2004 Michael Jung
5c2c66affSColin Finck  *
6c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck  * License as published by the Free Software Foundation; either
9c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck  *
11c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14c2c66affSColin Finck  * Lesser General Public License for more details.
15c2c66affSColin Finck  *
16c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19c2c66affSColin Finck  */
20c2c66affSColin Finck 
213c1b7834SAmine Khaldi #include <stdarg.h>
22c2c66affSColin Finck 
23*47854962SEric Kohl #include "ntstatus.h"
24*47854962SEric Kohl #define WIN32_NO_STATUS
253c1b7834SAmine Khaldi #include "windef.h"
263c1b7834SAmine Khaldi #include "winbase.h"
273c1b7834SAmine Khaldi #include "wincrypt.h"
283c1b7834SAmine Khaldi #include "winerror.h"
293c1b7834SAmine Khaldi #include "winreg.h"
303c1b7834SAmine Khaldi 
313c1b7834SAmine Khaldi #include "wine/test.h"
32c2c66affSColin Finck 
33ffd1293fSEric Kohl struct ustring {
34ffd1293fSEric Kohl     DWORD Length;
35ffd1293fSEric Kohl     DWORD MaximumLength;
36ffd1293fSEric Kohl     unsigned char *Buffer;
37ffd1293fSEric Kohl };
38ffd1293fSEric Kohl 
39c2c66affSColin Finck static const char szRsaBaseProv[] = MS_DEF_PROV_A;
40c2c66affSColin Finck static const char szNonExistentProv[] = "Wine Nonexistent Cryptographic Provider v11.2";
41c2c66affSColin Finck static const char szKeySet[] = "wine_test_keyset";
42c2c66affSColin Finck static const char szBadKeySet[] = "wine_test_bad_keyset";
43c2c66affSColin Finck #define NON_DEF_PROV_TYPE 999
44c2c66affSColin Finck 
45c2c66affSColin Finck static BOOL (WINAPI *pCryptAcquireContextA)(HCRYPTPROV*,LPCSTR,LPCSTR,DWORD,DWORD);
46c2c66affSColin Finck static BOOL (WINAPI *pCryptEnumProviderTypesA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*);
47c2c66affSColin Finck static BOOL (WINAPI *pCryptEnumProvidersA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*);
48c2c66affSColin Finck static BOOL (WINAPI *pCryptGetDefaultProviderA)(DWORD, DWORD*, DWORD, LPSTR, DWORD*);
49c2c66affSColin Finck static BOOL (WINAPI *pCryptReleaseContext)(HCRYPTPROV, DWORD);
50c2c66affSColin Finck static BOOL (WINAPI *pCryptSetProviderExA)(LPCSTR, DWORD, DWORD*, DWORD);
51c2c66affSColin Finck static BOOL (WINAPI *pCryptCreateHash)(HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, HCRYPTHASH*);
52c2c66affSColin Finck static BOOL (WINAPI *pCryptDestroyHash)(HCRYPTHASH);
53c2c66affSColin Finck static BOOL (WINAPI *pCryptGenRandom)(HCRYPTPROV, DWORD, BYTE*);
54c2c66affSColin Finck static BOOL (WINAPI *pCryptContextAddRef)(HCRYPTPROV, DWORD*, DWORD dwFlags);
55c2c66affSColin Finck static BOOL (WINAPI *pCryptGenKey)(HCRYPTPROV, ALG_ID, DWORD, HCRYPTKEY*);
56c2c66affSColin Finck static BOOL (WINAPI *pCryptDestroyKey)(HCRYPTKEY);
57c2c66affSColin Finck static BOOL (WINAPI *pCryptDecrypt)(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE*, DWORD*);
58c2c66affSColin Finck static BOOL (WINAPI *pCryptDeriveKey)(HCRYPTPROV, ALG_ID, HCRYPTHASH, DWORD, HCRYPTKEY*);
59c2c66affSColin Finck static BOOL (WINAPI *pCryptDuplicateHash)(HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
60c2c66affSColin Finck static BOOL (WINAPI *pCryptDuplicateKey)(HCRYPTKEY, DWORD*, DWORD, HCRYPTKEY*);
61c2c66affSColin Finck static BOOL (WINAPI *pCryptEncrypt)(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE*, DWORD*, DWORD);
62c2c66affSColin Finck static BOOL (WINAPI *pCryptExportKey)(HCRYPTKEY, HCRYPTKEY, DWORD, DWORD, BYTE*, DWORD*);
63c2c66affSColin Finck static BOOL (WINAPI *pCryptGetHashParam)(HCRYPTHASH, DWORD, BYTE*, DWORD*, DWORD);
64c2c66affSColin Finck static BOOL (WINAPI *pCryptGetKeyParam)(HCRYPTKEY, DWORD, BYTE*, DWORD*, DWORD);
65c2c66affSColin Finck static BOOL (WINAPI *pCryptGetProvParam)(HCRYPTPROV, DWORD, BYTE*, DWORD*, DWORD);
66c2c66affSColin Finck static BOOL (WINAPI *pCryptGetUserKey)(HCRYPTPROV, DWORD, HCRYPTKEY*);
67c2c66affSColin Finck static BOOL (WINAPI *pCryptHashData)(HCRYPTHASH, BYTE*, DWORD, DWORD);
68c2c66affSColin Finck static BOOL (WINAPI *pCryptHashSessionKey)(HCRYPTHASH, HCRYPTKEY, DWORD);
69c2c66affSColin Finck static BOOL (WINAPI *pCryptImportKey)(HCRYPTPROV, BYTE*, DWORD, HCRYPTKEY, DWORD, HCRYPTKEY*);
70c2c66affSColin Finck static BOOL (WINAPI *pCryptSignHashW)(HCRYPTHASH, DWORD, LPCWSTR, DWORD, BYTE*, DWORD*);
71c2c66affSColin Finck static BOOL (WINAPI *pCryptSetHashParam)(HCRYPTKEY, DWORD, BYTE*, DWORD);
72c2c66affSColin Finck static BOOL (WINAPI *pCryptSetKeyParam)(HCRYPTKEY, DWORD, BYTE*, DWORD);
73c2c66affSColin Finck static BOOL (WINAPI *pCryptSetProvParam)(HCRYPTPROV, DWORD, BYTE*, DWORD);
74c2c66affSColin Finck static BOOL (WINAPI *pCryptVerifySignatureW)(HCRYPTHASH, BYTE*, DWORD, HCRYPTKEY, LPCWSTR, DWORD);
75ffd1293fSEric Kohl static NTSTATUS (WINAPI *pSystemFunction004)(struct ustring*,struct ustring*, struct ustring*);
76ffd1293fSEric Kohl static NTSTATUS (WINAPI *pSystemFunction005)(struct ustring*,struct ustring*, struct ustring*);
77c2c66affSColin Finck static BOOLEAN (WINAPI *pSystemFunction036)(PVOID, ULONG);
78c2c66affSColin Finck 
init_function_pointers(void)79c2c66affSColin Finck static void init_function_pointers(void)
80c2c66affSColin Finck {
81c2c66affSColin Finck     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
82c2c66affSColin Finck 
83c2c66affSColin Finck     pCryptAcquireContextA = (void*)GetProcAddress(hadvapi32, "CryptAcquireContextA");
84c2c66affSColin Finck     pCryptEnumProviderTypesA = (void*)GetProcAddress(hadvapi32, "CryptEnumProviderTypesA");
85c2c66affSColin Finck     pCryptEnumProvidersA = (void*)GetProcAddress(hadvapi32, "CryptEnumProvidersA");
86c2c66affSColin Finck     pCryptGetDefaultProviderA = (void*)GetProcAddress(hadvapi32, "CryptGetDefaultProviderA");
87c2c66affSColin Finck     pCryptReleaseContext = (void*)GetProcAddress(hadvapi32, "CryptReleaseContext");
88c2c66affSColin Finck     pCryptSetProviderExA = (void*)GetProcAddress(hadvapi32, "CryptSetProviderExA");
89c2c66affSColin Finck     pCryptCreateHash = (void*)GetProcAddress(hadvapi32, "CryptCreateHash");
90c2c66affSColin Finck     pCryptDestroyHash = (void*)GetProcAddress(hadvapi32, "CryptDestroyHash");
91c2c66affSColin Finck     pCryptGenRandom = (void*)GetProcAddress(hadvapi32, "CryptGenRandom");
92c2c66affSColin Finck     pCryptContextAddRef = (void*)GetProcAddress(hadvapi32, "CryptContextAddRef");
93c2c66affSColin Finck     pCryptGenKey = (void*)GetProcAddress(hadvapi32, "CryptGenKey");
94c2c66affSColin Finck     pCryptDestroyKey = (void*)GetProcAddress(hadvapi32, "CryptDestroyKey");
95c2c66affSColin Finck     pCryptDecrypt = (void*)GetProcAddress(hadvapi32, "CryptDecrypt");
96c2c66affSColin Finck     pCryptDeriveKey = (void*)GetProcAddress(hadvapi32, "CryptDeriveKey");
97c2c66affSColin Finck     pCryptDuplicateHash = (void*)GetProcAddress(hadvapi32, "CryptDuplicateHash");
98c2c66affSColin Finck     pCryptDuplicateKey = (void*)GetProcAddress(hadvapi32, "CryptDuplicateKey");
99c2c66affSColin Finck     pCryptEncrypt = (void*)GetProcAddress(hadvapi32, "CryptEncrypt");
100c2c66affSColin Finck     pCryptExportKey = (void*)GetProcAddress(hadvapi32, "CryptExportKey");
101c2c66affSColin Finck     pCryptGetHashParam = (void*)GetProcAddress(hadvapi32, "CryptGetHashParam");
102c2c66affSColin Finck     pCryptGetKeyParam = (void*)GetProcAddress(hadvapi32, "CryptGetKeyParam");
103c2c66affSColin Finck     pCryptGetProvParam = (void*)GetProcAddress(hadvapi32, "CryptGetProvParam");
104c2c66affSColin Finck     pCryptGetUserKey = (void*)GetProcAddress(hadvapi32, "CryptGetUserKey");
105c2c66affSColin Finck     pCryptHashData = (void*)GetProcAddress(hadvapi32, "CryptHashData");
106c2c66affSColin Finck     pCryptHashSessionKey = (void*)GetProcAddress(hadvapi32, "CryptHashSessionKey");
107c2c66affSColin Finck     pCryptImportKey = (void*)GetProcAddress(hadvapi32, "CryptImportKey");
108c2c66affSColin Finck     pCryptSignHashW = (void*)GetProcAddress(hadvapi32, "CryptSignHashW");
109c2c66affSColin Finck     pCryptSetHashParam = (void*)GetProcAddress(hadvapi32, "CryptSetHashParam");
110c2c66affSColin Finck     pCryptSetKeyParam = (void*)GetProcAddress(hadvapi32, "CryptSetKeyParam");
111c2c66affSColin Finck     pCryptSetProvParam = (void*)GetProcAddress(hadvapi32, "CryptSetProvParam");
112c2c66affSColin Finck     pCryptVerifySignatureW = (void*)GetProcAddress(hadvapi32, "CryptVerifySignatureW");
113ffd1293fSEric Kohl     pSystemFunction004 = (void*)GetProcAddress(hadvapi32, "SystemFunction004");
114ffd1293fSEric Kohl     pSystemFunction005 = (void*)GetProcAddress(hadvapi32, "SystemFunction005");
115c2c66affSColin Finck     pSystemFunction036 = (void*)GetProcAddress(hadvapi32, "SystemFunction036");
116c2c66affSColin Finck }
117c2c66affSColin Finck 
init_environment(void)118c2c66affSColin Finck static void init_environment(void)
119c2c66affSColin Finck {
120c2c66affSColin Finck 	HCRYPTPROV hProv;
121c2c66affSColin Finck 
122c2c66affSColin Finck 	/* Ensure that container "wine_test_keyset" does exist */
123c2c66affSColin Finck 	if (!pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
124c2c66affSColin Finck 	{
125c2c66affSColin Finck 		pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_NEWKEYSET);
126c2c66affSColin Finck 	}
127c2c66affSColin Finck 	pCryptReleaseContext(hProv, 0);
128c2c66affSColin Finck 
129c2c66affSColin Finck 	/* Ensure that container "wine_test_keyset" does exist in default PROV_RSA_FULL type provider */
130c2c66affSColin Finck 	if (!pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))
131c2c66affSColin Finck 	{
132c2c66affSColin Finck 		pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET);
133c2c66affSColin Finck 	}
134c2c66affSColin Finck 	pCryptReleaseContext(hProv, 0);
135c2c66affSColin Finck 
136c2c66affSColin Finck 	/* Ensure that container "wine_test_bad_keyset" does not exist. */
137c2c66affSColin Finck 	if (pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
138c2c66affSColin Finck 	{
139c2c66affSColin Finck 		pCryptReleaseContext(hProv, 0);
140c2c66affSColin Finck 		pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
141c2c66affSColin Finck 	}
142c2c66affSColin Finck }
143c2c66affSColin Finck 
clean_up_environment(void)144c2c66affSColin Finck static void clean_up_environment(void)
145c2c66affSColin Finck {
146c2c66affSColin Finck 	HCRYPTPROV hProv;
147c2c66affSColin Finck 
148c2c66affSColin Finck 	/* Remove container "wine_test_keyset" */
149c2c66affSColin Finck 	if (pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
150c2c66affSColin Finck 	{
151c2c66affSColin Finck 		pCryptReleaseContext(hProv, 0);
152c2c66affSColin Finck 		pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
153c2c66affSColin Finck 	}
154c2c66affSColin Finck 
155c2c66affSColin Finck 	/* Remove container "wine_test_keyset" from default PROV_RSA_FULL type provider */
156c2c66affSColin Finck 	if (pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))
157c2c66affSColin Finck 	{
158c2c66affSColin Finck 		pCryptReleaseContext(hProv, 0);
159c2c66affSColin Finck 		pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
160c2c66affSColin Finck 	}
161c2c66affSColin Finck 
162c2c66affSColin Finck         /* Remove container "wine_test_bad_keyset" */
163c2c66affSColin Finck         if (pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
164c2c66affSColin Finck         {
165c2c66affSColin Finck                 pCryptReleaseContext(hProv, 0);
166c2c66affSColin Finck                 pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
167c2c66affSColin Finck         }
168c2c66affSColin Finck }
169c2c66affSColin Finck 
test_acquire_context(void)170c2c66affSColin Finck static void test_acquire_context(void)
171c2c66affSColin Finck {
172c2c66affSColin Finck 	BOOL result;
173c2c66affSColin Finck 	HCRYPTPROV hProv;
174c2c66affSColin Finck 	DWORD GLE;
175c2c66affSColin Finck 
176c2c66affSColin Finck 	/* Provoke all kinds of error conditions (which are easy to provoke).
177c2c66affSColin Finck 	 * The order of the error tests seems to match Windows XP's rsaenh.dll CSP,
178c2c66affSColin Finck 	 * but since this is likely to change between CSP versions, we don't check
179c2c66affSColin Finck 	 * this. Please don't change the order of tests. */
180c2c66affSColin Finck 	result = pCryptAcquireContextA(&hProv, NULL, NULL, 0, 0);
181c2c66affSColin Finck 	ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError());
182c2c66affSColin Finck 
183c2c66affSColin Finck 	result = pCryptAcquireContextA(&hProv, NULL, NULL, 1000, 0);
184c2c66affSColin Finck 	ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError());
185c2c66affSColin Finck 
186c2c66affSColin Finck 	result = pCryptAcquireContextA(&hProv, NULL, NULL, NON_DEF_PROV_TYPE, 0);
187c2c66affSColin Finck 	ok(!result && GetLastError()==NTE_PROV_TYPE_NOT_DEF, "%d\n", GetLastError());
188c2c66affSColin Finck 
189c2c66affSColin Finck 	result = pCryptAcquireContextA(&hProv, szKeySet, szNonExistentProv, PROV_RSA_FULL, 0);
190c2c66affSColin Finck 	ok(!result && GetLastError()==NTE_KEYSET_NOT_DEF, "%d\n", GetLastError());
191c2c66affSColin Finck 
192c2c66affSColin Finck 	result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, NON_DEF_PROV_TYPE, 0);
193c2c66affSColin Finck 	ok(!result && GetLastError()==NTE_PROV_TYPE_NO_MATCH, "%d\n", GetLastError());
194c2c66affSColin Finck 
195c2c66affSColin Finck 	/* This test fails under Win2k SP4:
196c2c66affSColin Finck 	   result = TRUE, GetLastError() == ERROR_INVALID_PARAMETER
197c2c66affSColin Finck 	SetLastError(0xdeadbeef);
198c2c66affSColin Finck 	result = pCryptAcquireContextA(NULL, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
199c2c66affSColin Finck 	ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d/%d\n", result, GetLastError());
200c2c66affSColin Finck 	*/
201c2c66affSColin Finck 
202c2c66affSColin Finck 	/* Last not least, try to really acquire a context. */
203c2c66affSColin Finck 	hProv = 0;
204c2c66affSColin Finck 	SetLastError(0xdeadbeef);
205c2c66affSColin Finck 	result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
206c2c66affSColin Finck 	GLE = GetLastError();
207c2c66affSColin Finck 	ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND   ||
208c2c66affSColin Finck 		      GLE == ERROR_SUCCESS            ||
209c2c66affSColin Finck 		      GLE == ERROR_RING2_STACK_IN_USE ||
210c2c66affSColin Finck 		      GLE == NTE_FAIL                 ||
211c2c66affSColin Finck 		      GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GLE);
212c2c66affSColin Finck 
213c2c66affSColin Finck 	if (hProv)
214c2c66affSColin Finck 		pCryptReleaseContext(hProv, 0);
215c2c66affSColin Finck 
216c2c66affSColin Finck 	/* Try again, witch an empty ("\0") szProvider parameter */
217c2c66affSColin Finck 	hProv = 0;
218c2c66affSColin Finck 	SetLastError(0xdeadbeef);
219c2c66affSColin Finck 	result = pCryptAcquireContextA(&hProv, szKeySet, "", PROV_RSA_FULL, 0);
220c2c66affSColin Finck 	GLE = GetLastError();
221c2c66affSColin Finck 	ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND   ||
222c2c66affSColin Finck 		      GLE == ERROR_SUCCESS            ||
223c2c66affSColin Finck 		      GLE == ERROR_RING2_STACK_IN_USE ||
224c2c66affSColin Finck 		      GLE == NTE_FAIL                 ||
225c2c66affSColin Finck 		      GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GetLastError());
226c2c66affSColin Finck 
227c2c66affSColin Finck 	if (hProv)
228c2c66affSColin Finck 		pCryptReleaseContext(hProv, 0);
229c2c66affSColin Finck }
230c2c66affSColin Finck 
test_incorrect_api_usage(void)231c2c66affSColin Finck static void test_incorrect_api_usage(void)
232c2c66affSColin Finck {
233c2c66affSColin Finck     BOOL result;
234c2c66affSColin Finck     HCRYPTPROV hProv, hProv2;
235c2c66affSColin Finck     HCRYPTHASH hHash, hHash2;
236c2c66affSColin Finck     HCRYPTKEY hKey, hKey2;
237c2c66affSColin Finck     BYTE temp;
238c2c66affSColin Finck     DWORD dwLen, dwTemp;
239c2c66affSColin Finck 
240c2c66affSColin Finck     /* This is to document incorrect api usage in the
241c2c66affSColin Finck      * "Uru - Ages beyond Myst Demo" installer as reported by Paul Vriens.
242c2c66affSColin Finck      *
243c2c66affSColin Finck      * The installer destroys a hash object after having released the context
244c2c66affSColin Finck      * with which the hash was created. This is not allowed according to MSDN,
245c2c66affSColin Finck      * since CryptReleaseContext destroys all hash and key objects belonging to
246c2c66affSColin Finck      * the respective context. However, while wine used to crash, Windows is more
247c2c66affSColin Finck      * robust here and returns an ERROR_INVALID_PARAMETER code.
248c2c66affSColin Finck      */
249c2c66affSColin Finck 
250c2c66affSColin Finck     result = pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv,
251c2c66affSColin Finck                                    PROV_RSA_FULL, CRYPT_NEWKEYSET);
252c2c66affSColin Finck     ok (result, "%08x\n", GetLastError());
253c2c66affSColin Finck     if (!result) return;
254c2c66affSColin Finck 
255c2c66affSColin Finck     result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
256c2c66affSColin Finck     ok (result, "%d\n", GetLastError());
257c2c66affSColin Finck     if (!result) return;
258c2c66affSColin Finck     pCryptDestroyHash(hHash);
259c2c66affSColin Finck 
260c2c66affSColin Finck     result = pCryptCreateHash(0, CALG_SHA, 0, 0, &hHash);
261c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
262c2c66affSColin Finck 
263c2c66affSColin Finck     result = pCryptGenKey(0, CALG_RC4, 0, &hKey);
264c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
265c2c66affSColin Finck 
266c2c66affSColin Finck     result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey);
267c2c66affSColin Finck     ok (result, "%d\n", GetLastError());
268c2c66affSColin Finck     if (!result) return;
269c2c66affSColin Finck 
270c2c66affSColin Finck     result = pCryptDestroyKey(hKey);
271c2c66affSColin Finck     ok (result, "%d\n", GetLastError());
272c2c66affSColin Finck 
273c2c66affSColin Finck     result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
274c2c66affSColin Finck     ok (result, "%d\n", GetLastError());
275c2c66affSColin Finck     if (!result) return;
276c2c66affSColin Finck 
277c2c66affSColin Finck     result = pCryptDestroyKey(hKey2);
278c2c66affSColin Finck     ok (result, "%d\n", GetLastError());
279c2c66affSColin Finck 
280c2c66affSColin Finck     dwTemp = CRYPT_MODE_ECB;
281c2c66affSColin Finck     result = pCryptSetKeyParam(hKey2, KP_MODE, (BYTE*)&dwTemp, sizeof(DWORD));
282c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
283c2c66affSColin Finck 
284c2c66affSColin Finck     result = pCryptAcquireContextA(&hProv2, szBadKeySet, NULL, PROV_RSA_FULL,
285c2c66affSColin Finck                                    CRYPT_DELETEKEYSET);
286c2c66affSColin Finck     ok (result, "%d\n", GetLastError());
287c2c66affSColin Finck     if (!result) return;
288c2c66affSColin Finck 
289c2c66affSColin Finck     result = pCryptReleaseContext(hProv, 0);
290c2c66affSColin Finck     ok (result, "%d\n", GetLastError());
291c2c66affSColin Finck     if (!result) return;
292c2c66affSColin Finck 
293c2c66affSColin Finck     result = pCryptReleaseContext(hProv, 0);
294c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
295c2c66affSColin Finck 
296c2c66affSColin Finck     result = pCryptGenRandom(hProv, 1, &temp);
297c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
298c2c66affSColin Finck 
299c2c66affSColin Finck #ifdef CRASHES_ON_NT40
300c2c66affSColin Finck     result = pCryptContextAddRef(hProv, NULL, 0);
301c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
302c2c66affSColin Finck #endif
303c2c66affSColin Finck 
304c2c66affSColin Finck     result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
305c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
306c2c66affSColin Finck 
307c2c66affSColin Finck     dwLen = 1;
308c2c66affSColin Finck     result = pCryptDecrypt(hKey, 0, TRUE, 0, &temp, &dwLen);
309c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
310c2c66affSColin Finck 
311c2c66affSColin Finck     dwLen = 1;
312c2c66affSColin Finck     result = pCryptEncrypt(hKey, 0, TRUE, 0, &temp, &dwLen, 1);
313c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
314c2c66affSColin Finck 
315c2c66affSColin Finck     result = pCryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey2);
316c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
317c2c66affSColin Finck 
318c2c66affSColin Finck #ifdef CRASHES_ON_NT40
319c2c66affSColin Finck     result = pCryptDuplicateHash(hHash, NULL, 0, &hHash2);
320c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
321c2c66affSColin Finck 
322c2c66affSColin Finck     result = pCryptDuplicateKey(hKey, NULL, 0, &hKey2);
323c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
324c2c66affSColin Finck #endif
325c2c66affSColin Finck 
326c2c66affSColin Finck     dwLen = 1;
327c2c66affSColin Finck     result = pCryptExportKey(hKey, 0, 0, 0, &temp, &dwLen);
328c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
329c2c66affSColin Finck 
330c2c66affSColin Finck     result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
331c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
332c2c66affSColin Finck 
333c2c66affSColin Finck     dwLen = 1;
334c2c66affSColin Finck     result = pCryptGetHashParam(hHash, 0, &temp, &dwLen, 0);
335c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
336c2c66affSColin Finck 
337c2c66affSColin Finck     dwLen = 1;
338c2c66affSColin Finck     result = pCryptGetKeyParam(hKey, 0, &temp, &dwLen, 0);
339c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
340c2c66affSColin Finck 
341c2c66affSColin Finck     dwLen = 1;
342c2c66affSColin Finck     result = pCryptGetProvParam(hProv, 0, &temp, &dwLen, 0);
343c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
344c2c66affSColin Finck 
345c2c66affSColin Finck     result = pCryptGetUserKey(hProv, 0, &hKey2);
346c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
347c2c66affSColin Finck 
348c2c66affSColin Finck     result = pCryptHashData(hHash, &temp, 1, 0);
349c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
350c2c66affSColin Finck 
351c2c66affSColin Finck     result = pCryptHashSessionKey(hHash, hKey, 0);
352c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
353c2c66affSColin Finck 
354c2c66affSColin Finck     result = pCryptImportKey(hProv, &temp, 1, 0, 0, &hKey2);
355c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
356c2c66affSColin Finck 
357c2c66affSColin Finck     if (pCryptSignHashW)
358c2c66affSColin Finck     {
359c2c66affSColin Finck         dwLen = 1;
360c2c66affSColin Finck         result = pCryptSignHashW(hHash, 0, NULL, 0, &temp, &dwLen);
361c2c66affSColin Finck         ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
362c2c66affSColin Finck             GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
363c2c66affSColin Finck     }
364c2c66affSColin Finck     else
365c2c66affSColin Finck         win_skip("CryptSignHashW is not available\n");
366c2c66affSColin Finck 
367c2c66affSColin Finck     result = pCryptSetKeyParam(hKey, 0, &temp, 1);
368c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
369c2c66affSColin Finck 
370c2c66affSColin Finck     result = pCryptSetHashParam(hHash, 0, &temp, 1);
371c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
372c2c66affSColin Finck 
373c2c66affSColin Finck     result = pCryptSetProvParam(hProv, 0, &temp, 1);
374c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
375c2c66affSColin Finck 
376c2c66affSColin Finck     if (pCryptVerifySignatureW)
377c2c66affSColin Finck     {
378c2c66affSColin Finck         result = pCryptVerifySignatureW(hHash, &temp, 1, hKey, NULL, 0);
379c2c66affSColin Finck         ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
380c2c66affSColin Finck             GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
381c2c66affSColin Finck     }
382c2c66affSColin Finck     else
383c2c66affSColin Finck         win_skip("CryptVerifySignatureW is not available\n");
384c2c66affSColin Finck 
385c2c66affSColin Finck     result = pCryptDestroyHash(hHash);
386c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
387c2c66affSColin Finck 
388c2c66affSColin Finck     result = pCryptDestroyKey(hKey);
389c2c66affSColin Finck     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
390c2c66affSColin Finck }
391c2c66affSColin Finck 
392c2c66affSColin Finck static const BYTE privKey[] = {
393c2c66affSColin Finck  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
394c2c66affSColin Finck  0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
395c2c66affSColin Finck  0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
396c2c66affSColin Finck  0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
397c2c66affSColin Finck  0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
398c2c66affSColin Finck  0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
399c2c66affSColin Finck  0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
400c2c66affSColin Finck  0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
401c2c66affSColin Finck  0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
402c2c66affSColin Finck  0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
403c2c66affSColin Finck  0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
404c2c66affSColin Finck  0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
405c2c66affSColin Finck  0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
406c2c66affSColin Finck  0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
407c2c66affSColin Finck  0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
408c2c66affSColin Finck  0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
409c2c66affSColin Finck  0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
410c2c66affSColin Finck  0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
411c2c66affSColin Finck  0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
412c2c66affSColin Finck  0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
413c2c66affSColin Finck  0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
414c2c66affSColin Finck  0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
415c2c66affSColin Finck  0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
416c2c66affSColin Finck  0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
417c2c66affSColin Finck 
test_verify_sig(void)418c2c66affSColin Finck static void test_verify_sig(void)
419c2c66affSColin Finck {
420c2c66affSColin Finck 	BOOL ret;
421c2c66affSColin Finck 	HCRYPTPROV prov;
422c2c66affSColin Finck 	HCRYPTKEY key;
423c2c66affSColin Finck 	HCRYPTHASH hash;
424c2c66affSColin Finck 	BYTE bogus[] = { 0 };
425c2c66affSColin Finck 
426c2c66affSColin Finck 	if (!pCryptVerifySignatureW)
427c2c66affSColin Finck 	{
428c2c66affSColin Finck 		win_skip("CryptVerifySignatureW is not available\n");
429c2c66affSColin Finck 		return;
430c2c66affSColin Finck 	}
431c2c66affSColin Finck 
432c2c66affSColin Finck 	SetLastError(0xdeadbeef);
433c2c66affSColin Finck 	ret = pCryptVerifySignatureW(0, NULL, 0, 0, NULL, 0);
434c2c66affSColin Finck 	if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
435c2c66affSColin Finck 	{
436c2c66affSColin Finck 		win_skip("CryptVerifySignatureW is not implemented\n");
437c2c66affSColin Finck 		return;
438c2c66affSColin Finck 	}
439c2c66affSColin Finck 	ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
440c2c66affSColin Finck 	 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
441c2c66affSColin Finck 	ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL,
442c2c66affSColin Finck 	 CRYPT_NEWKEYSET);
443c2c66affSColin Finck 	if (!ret && GetLastError() == NTE_EXISTS)
444c2c66affSColin Finck 		ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL, 0);
445c2c66affSColin Finck 	ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
446c2c66affSColin Finck 	ret = pCryptImportKey(prov, (LPBYTE)privKey, sizeof(privKey), 0, 0, &key);
447c2c66affSColin Finck 	ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
448c2c66affSColin Finck 	ret = pCryptCreateHash(prov, CALG_MD5, 0, 0, &hash);
449c2c66affSColin Finck 	ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
450c2c66affSColin Finck 	SetLastError(0xdeadbeef);
451c2c66affSColin Finck 	ret = pCryptVerifySignatureW(hash, NULL, 0, 0, NULL, 0);
452c2c66affSColin Finck 	ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
453c2c66affSColin Finck 	 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
454c2c66affSColin Finck 	SetLastError(0xdeadbeef);
455c2c66affSColin Finck 	ret = pCryptVerifySignatureW(0, NULL, 0, key, NULL, 0);
456c2c66affSColin Finck 	ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
457c2c66affSColin Finck 	 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
458c2c66affSColin Finck 	SetLastError(0xdeadbeef);
459c2c66affSColin Finck 	ret = pCryptVerifySignatureW(hash, NULL, 0, key, NULL, 0);
460c2c66affSColin Finck 	ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
461c2c66affSColin Finck 	 GetLastError() == ERROR_INVALID_PARAMETER),
462c2c66affSColin Finck 	 "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
463c2c66affSColin Finck 	 GetLastError());
464c2c66affSColin Finck 	SetLastError(0xdeadbeef);
465c2c66affSColin Finck 	ret = pCryptVerifySignatureW(hash, NULL, sizeof(bogus), key, NULL, 0);
466c2c66affSColin Finck 	ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
467c2c66affSColin Finck 	 GetLastError() == ERROR_INVALID_PARAMETER),
468c2c66affSColin Finck 	 "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
469c2c66affSColin Finck 	 GetLastError());
470c2c66affSColin Finck 	SetLastError(0xdeadbeef);
471c2c66affSColin Finck 	ret = pCryptVerifySignatureW(hash, bogus, 0, key, NULL, 0);
472c2c66affSColin Finck 	ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
473c2c66affSColin Finck 	 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
474c2c66affSColin Finck 	SetLastError(0xdeadbeef);
475c2c66affSColin Finck 	ret = pCryptVerifySignatureW(hash, bogus, sizeof(bogus), key, NULL, 0);
476c2c66affSColin Finck 	ok(!ret &&
477c2c66affSColin Finck          (GetLastError() == NTE_BAD_SIGNATURE ||
478c2c66affSColin Finck          broken(GetLastError() == NTE_BAD_HASH_STATE /* older NT4 */)),
479c2c66affSColin Finck 	 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
480c2c66affSColin Finck 	pCryptDestroyKey(key);
481c2c66affSColin Finck 	pCryptDestroyHash(hash);
482c2c66affSColin Finck 	pCryptReleaseContext(prov, 0);
483c2c66affSColin Finck }
484c2c66affSColin Finck 
FindProvRegVals(DWORD dwIndex,DWORD * pdwProvType,LPSTR * pszProvName,DWORD * pcbProvName,DWORD * pdwProvCount)485c2c66affSColin Finck static BOOL FindProvRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszProvName,
486c2c66affSColin Finck 			    DWORD *pcbProvName, DWORD *pdwProvCount)
487c2c66affSColin Finck {
488c2c66affSColin Finck 	HKEY hKey;
489c2c66affSColin Finck 	HKEY subkey;
490c2c66affSColin Finck 	DWORD size = sizeof(DWORD);
491c2c66affSColin Finck 
492c2c66affSColin Finck 	if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider", &hKey))
493c2c66affSColin Finck 		return FALSE;
494c2c66affSColin Finck 
495c2c66affSColin Finck 	RegQueryInfoKeyA(hKey, NULL, NULL, NULL, pdwProvCount, pcbProvName,
496c2c66affSColin Finck 				 NULL, NULL, NULL, NULL, NULL, NULL);
497c2c66affSColin Finck 	(*pcbProvName)++;
498c2c66affSColin Finck 
499c2c66affSColin Finck 	if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))
500c2c66affSColin Finck 		return FALSE;
501c2c66affSColin Finck 
502c2c66affSColin Finck 	RegEnumKeyExA(hKey, dwIndex, *pszProvName, pcbProvName, NULL, NULL, NULL, NULL);
503c2c66affSColin Finck 	(*pcbProvName)++;
504c2c66affSColin Finck 
505c2c66affSColin Finck 	RegOpenKeyA(hKey, *pszProvName, &subkey);
506c2c66affSColin Finck 	RegQueryValueExA(subkey, "Type", NULL, NULL, (LPBYTE)pdwProvType, &size);
507c2c66affSColin Finck 
508c2c66affSColin Finck 	RegCloseKey(subkey);
509c2c66affSColin Finck 	RegCloseKey(hKey);
510c2c66affSColin Finck 
511c2c66affSColin Finck 	return TRUE;
512c2c66affSColin Finck }
513c2c66affSColin Finck 
test_enum_providers(void)514c2c66affSColin Finck static void test_enum_providers(void)
515c2c66affSColin Finck {
516c2c66affSColin Finck 	/* expected results */
517c2c66affSColin Finck 	CHAR *pszProvName = NULL;
518c2c66affSColin Finck 	DWORD cbName;
519c2c66affSColin Finck 	DWORD dwType;
520c2c66affSColin Finck 	DWORD provCount;
521c2c66affSColin Finck 	DWORD dwIndex = 0;
522c2c66affSColin Finck 
523c2c66affSColin Finck 	/* actual results */
524c2c66affSColin Finck 	CHAR *provider = NULL;
525c2c66affSColin Finck 	DWORD providerLen;
526c2c66affSColin Finck 	DWORD type;
527c2c66affSColin Finck 	DWORD count;
528c2c66affSColin Finck 	DWORD result;
529c2c66affSColin Finck 	DWORD notNull = 5;
530c2c66affSColin Finck 	DWORD notZeroFlags = 5;
531c2c66affSColin Finck 
532c2c66affSColin Finck 	if(!pCryptEnumProvidersA)
533c2c66affSColin Finck 	{
534c2c66affSColin Finck 	    win_skip("CryptEnumProvidersA is not available\n");
535c2c66affSColin Finck 	    return;
536c2c66affSColin Finck 	}
537c2c66affSColin Finck 
538c2c66affSColin Finck 	if (!FindProvRegVals(dwIndex, &dwType, &pszProvName, &cbName, &provCount))
539c2c66affSColin Finck 	{
540c2c66affSColin Finck 	    win_skip("Could not find providers in registry\n");
541c2c66affSColin Finck 	    return;
542c2c66affSColin Finck 	}
543c2c66affSColin Finck 
544c2c66affSColin Finck 	/* check pdwReserved flag for NULL */
545c2c66affSColin Finck 	result = pCryptEnumProvidersA(dwIndex, &notNull, 0, &type, NULL, &providerLen);
546c2c66affSColin Finck 	ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
547c2c66affSColin Finck 
548c2c66affSColin Finck 	/* check dwFlags == 0 */
549c2c66affSColin Finck 	result = pCryptEnumProvidersA(dwIndex, NULL, notZeroFlags, &type, NULL, &providerLen);
550c2c66affSColin Finck 	ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d\n", GetLastError());
551c2c66affSColin Finck 
552c2c66affSColin Finck 	/* alloc provider to half the size required
553c2c66affSColin Finck 	 * cbName holds the size required */
554c2c66affSColin Finck 	providerLen = cbName / 2;
555c2c66affSColin Finck 	if (!(provider = LocalAlloc(LMEM_ZEROINIT, providerLen)))
556c2c66affSColin Finck 		return;
557c2c66affSColin Finck 
558c2c66affSColin Finck 	result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
559c2c66affSColin Finck 	ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
560c2c66affSColin Finck 		ERROR_MORE_DATA, GetLastError());
561c2c66affSColin Finck 
562c2c66affSColin Finck 	LocalFree(provider);
563c2c66affSColin Finck 
564c2c66affSColin Finck 	/* loop through the providers to get the number of providers
565c2c66affSColin Finck 	 * after loop ends, count should be provCount + 1 so subtract 1
566c2c66affSColin Finck 	 * to get actual number of providers */
567c2c66affSColin Finck 	count = 0;
568c2c66affSColin Finck 	while(pCryptEnumProvidersA(count++, NULL, 0, &type, NULL, &providerLen))
569c2c66affSColin Finck 		;
570c2c66affSColin Finck 	count--;
571c2c66affSColin Finck 	ok(count==provCount, "expected %i, got %i\n", (int)provCount, (int)count);
572c2c66affSColin Finck 
573c2c66affSColin Finck 	/* loop past the actual number of providers to get the error
574c2c66affSColin Finck 	 * ERROR_NO_MORE_ITEMS */
575c2c66affSColin Finck 	for (count = 0; count < provCount + 1; count++)
576c2c66affSColin Finck 		result = pCryptEnumProvidersA(count, NULL, 0, &type, NULL, &providerLen);
577c2c66affSColin Finck 	ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %d\n",
578c2c66affSColin Finck 			ERROR_NO_MORE_ITEMS, GetLastError());
579c2c66affSColin Finck 
580c2c66affSColin Finck 	/* check expected versus actual values returned */
581c2c66affSColin Finck 	result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, NULL, &providerLen);
582c2c66affSColin Finck 	ok(result && providerLen==cbName, "expected %i, got %i\n", (int)cbName, (int)providerLen);
583c2c66affSColin Finck 	if (!(provider = LocalAlloc(LMEM_ZEROINIT, providerLen)))
584c2c66affSColin Finck 		return;
585c2c66affSColin Finck 
586c2c66affSColin Finck 	providerLen = -1;
587c2c66affSColin Finck 	result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
588c2c66affSColin Finck 	ok(result, "expected TRUE, got %d\n", result);
589c2c66affSColin Finck 	ok(type==dwType, "expected %d, got %d\n", dwType, type);
590c2c66affSColin Finck 	if (pszProvName)
591c2c66affSColin Finck 	    ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
592c2c66affSColin Finck 	ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);
593c2c66affSColin Finck 
594c2c66affSColin Finck 	providerLen = -1000;
595c2c66affSColin Finck 	provider[0] = 0;
596c2c66affSColin Finck 	result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
597c2c66affSColin Finck 	ok(result, "expected TRUE, got %d\n", result);
598c2c66affSColin Finck 	ok(type==dwType, "expected %d, got %d\n", dwType, type);
599c2c66affSColin Finck 	if (pszProvName)
600c2c66affSColin Finck 	    ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
601c2c66affSColin Finck 	ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);
602c2c66affSColin Finck 
603c2c66affSColin Finck 	LocalFree(pszProvName);
604c2c66affSColin Finck 	LocalFree(provider);
605c2c66affSColin Finck }
606c2c66affSColin Finck 
FindProvTypesRegVals(DWORD * pdwIndex,DWORD * pdwProvType,LPSTR * pszTypeName,DWORD * pcbTypeName,DWORD * pdwTypeCount)607c2c66affSColin Finck static BOOL FindProvTypesRegVals(DWORD *pdwIndex, DWORD *pdwProvType, LPSTR *pszTypeName,
608c2c66affSColin Finck 				 DWORD *pcbTypeName, DWORD *pdwTypeCount)
609c2c66affSColin Finck {
610c2c66affSColin Finck 	HKEY hKey;
611c2c66affSColin Finck 	HKEY hSubKey;
612c2c66affSColin Finck 	PSTR ch;
613c2c66affSColin Finck 	LPSTR szName;
614c2c66affSColin Finck 	DWORD cbName;
615c2c66affSColin Finck 	BOOL ret = FALSE;
616c2c66affSColin Finck 
617c2c66affSColin Finck 	if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey))
618c2c66affSColin Finck 		return FALSE;
619c2c66affSColin Finck 
620c2c66affSColin Finck 	if (RegQueryInfoKeyA(hKey, NULL, NULL, NULL, pdwTypeCount, &cbName, NULL,
621c2c66affSColin Finck 			NULL, NULL, NULL, NULL, NULL))
622c2c66affSColin Finck 		goto cleanup;
623c2c66affSColin Finck 	cbName++;
624c2c66affSColin Finck 
625c2c66affSColin Finck 	if (!(szName = LocalAlloc(LMEM_ZEROINIT, cbName)))
626c2c66affSColin Finck 		goto cleanup;
627c2c66affSColin Finck 
628c2c66affSColin Finck 	while (!RegEnumKeyExA(hKey, *pdwIndex, szName, &cbName, NULL, NULL, NULL, NULL))
629c2c66affSColin Finck 	{
630c2c66affSColin Finck 		cbName++;
631c2c66affSColin Finck 		ch = szName + strlen(szName);
632c2c66affSColin Finck 		/* Convert "Type 000" to 0, etc/ */
633c2c66affSColin Finck 		*pdwProvType = *(--ch) - '0';
634c2c66affSColin Finck 		*pdwProvType += (*(--ch) - '0') * 10;
635c2c66affSColin Finck 		*pdwProvType += (*(--ch) - '0') * 100;
636c2c66affSColin Finck 
637c2c66affSColin Finck 		if (RegOpenKeyA(hKey, szName, &hSubKey))
638c2c66affSColin Finck 			break;
639c2c66affSColin Finck 
640c2c66affSColin Finck 		if (!RegQueryValueExA(hSubKey, "TypeName", NULL, NULL, NULL, pcbTypeName))
641c2c66affSColin Finck 		{
642c2c66affSColin Finck 			if (!(*pszTypeName = LocalAlloc(LMEM_ZEROINIT, *pcbTypeName)))
643c2c66affSColin Finck 				break;
644c2c66affSColin Finck 
645c2c66affSColin Finck 			if (!RegQueryValueExA(hSubKey, "TypeName", NULL, NULL, (LPBYTE)*pszTypeName, pcbTypeName))
646c2c66affSColin Finck 			{
647c2c66affSColin Finck 				ret = TRUE;
648c2c66affSColin Finck 				break;
649c2c66affSColin Finck 			}
650c2c66affSColin Finck 
651c2c66affSColin Finck 			LocalFree(*pszTypeName);
652c2c66affSColin Finck 		}
653c2c66affSColin Finck 
654c2c66affSColin Finck 		RegCloseKey(hSubKey);
655c2c66affSColin Finck 
656c2c66affSColin Finck 		(*pdwIndex)++;
657c2c66affSColin Finck 	}
658c2c66affSColin Finck 	RegCloseKey(hSubKey);
659c2c66affSColin Finck 	LocalFree(szName);
660c2c66affSColin Finck 
661c2c66affSColin Finck cleanup:
662c2c66affSColin Finck 	RegCloseKey(hKey);
663c2c66affSColin Finck 
664c2c66affSColin Finck 	return ret;
665c2c66affSColin Finck }
666c2c66affSColin Finck 
test_enum_provider_types(void)667c2c66affSColin Finck static void test_enum_provider_types(void)
668c2c66affSColin Finck {
669c2c66affSColin Finck 	/* expected values */
670c2c66affSColin Finck 	DWORD dwProvType = 0;
671c2c66affSColin Finck 	LPSTR pszTypeName = NULL;
672c2c66affSColin Finck 	DWORD cbTypeName;
673c2c66affSColin Finck 	DWORD dwTypeCount;
674c2c66affSColin Finck 
675c2c66affSColin Finck 	/* actual values */
676c2c66affSColin Finck 	DWORD index = 0;
677c2c66affSColin Finck 	DWORD provType;
678c2c66affSColin Finck 	LPSTR typeName = NULL;
679c2c66affSColin Finck 	DWORD typeNameSize;
680c2c66affSColin Finck 	DWORD typeCount;
681c2c66affSColin Finck 	DWORD result;
682c2c66affSColin Finck 	DWORD notNull = 5;
683c2c66affSColin Finck 	DWORD notZeroFlags = 5;
684c2c66affSColin Finck 
685c2c66affSColin Finck 	if(!pCryptEnumProviderTypesA)
686c2c66affSColin Finck 	{
687c2c66affSColin Finck 		win_skip("CryptEnumProviderTypesA is not available\n");
688c2c66affSColin Finck 		return;
689c2c66affSColin Finck 	}
690c2c66affSColin Finck 
691c2c66affSColin Finck 	if (!FindProvTypesRegVals(&index, &dwProvType, &pszTypeName, &cbTypeName, &dwTypeCount))
692c2c66affSColin Finck 	{
693c2c66affSColin Finck 		skip("Could not find provider types in registry\n");
694c2c66affSColin Finck 		return;
695c2c66affSColin Finck 	}
696c2c66affSColin Finck 
697c2c66affSColin Finck 	/* check pdwReserved for NULL */
698c2c66affSColin Finck 	result = pCryptEnumProviderTypesA(index, &notNull, 0, &provType, typeName, &typeNameSize);
699c2c66affSColin Finck 	ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n",
700c2c66affSColin Finck 		GetLastError());
701c2c66affSColin Finck 
702c2c66affSColin Finck 	/* check dwFlags == zero */
703c2c66affSColin Finck 	result = pCryptEnumProviderTypesA(index, NULL, notZeroFlags, &provType, typeName, &typeNameSize);
704c2c66affSColin Finck 	ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected ERROR_INVALID_PARAMETER, got %d\n",
705c2c66affSColin Finck 		GetLastError());
706c2c66affSColin Finck 
707c2c66affSColin Finck 	/* This test fails under Win2k SP4:
708c2c66affSColin Finck 	 * result = TRUE, GetLastError() == 0xdeadbeef */
709c2c66affSColin Finck 	if (0)
710c2c66affSColin Finck 	{
711c2c66affSColin Finck 		/* alloc provider type to half the size required
712c2c66affSColin Finck 		 * cbTypeName holds the size required */
713c2c66affSColin Finck 		typeNameSize = cbTypeName / 2;
714c2c66affSColin Finck 		if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize)))
715c2c66affSColin Finck 			goto cleanup;
716c2c66affSColin Finck 
717c2c66affSColin Finck 		SetLastError(0xdeadbeef);
718c2c66affSColin Finck 		result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
719c2c66affSColin Finck 		ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %d/%d\n",
720c2c66affSColin Finck 			result, GetLastError());
721c2c66affSColin Finck 
722c2c66affSColin Finck 		LocalFree(typeName);
723c2c66affSColin Finck 	}
724c2c66affSColin Finck 
725c2c66affSColin Finck 	/* loop through the provider types to get the number of provider types
726c2c66affSColin Finck 	 * after loop ends, count should be dwTypeCount + 1 so subtract 1
727c2c66affSColin Finck 	 * to get actual number of provider types */
728c2c66affSColin Finck 	typeCount = 0;
729c2c66affSColin Finck 	while(pCryptEnumProviderTypesA(typeCount++, NULL, 0, &provType, NULL, &typeNameSize))
730c2c66affSColin Finck 		;
731c2c66affSColin Finck 	typeCount--;
732c2c66affSColin Finck 	ok(typeCount==dwTypeCount, "expected %d, got %d\n", dwTypeCount, typeCount);
733c2c66affSColin Finck 
734c2c66affSColin Finck 	/* loop past the actual number of provider types to get the error
735c2c66affSColin Finck 	 * ERROR_NO_MORE_ITEMS */
736c2c66affSColin Finck 	for (typeCount = 0; typeCount < dwTypeCount + 1; typeCount++)
737c2c66affSColin Finck 		result = pCryptEnumProviderTypesA(typeCount, NULL, 0, &provType, NULL, &typeNameSize);
738c2c66affSColin Finck 	ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n",
739c2c66affSColin Finck 		GetLastError());
740c2c66affSColin Finck 
741c2c66affSColin Finck 	/* check expected versus actual values returned */
742c2c66affSColin Finck 	result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, NULL, &typeNameSize);
743c2c66affSColin Finck 	ok(result && typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
744c2c66affSColin Finck 	if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize)))
745c2c66affSColin Finck 		goto cleanup;
746c2c66affSColin Finck 
747c2c66affSColin Finck 	typeNameSize = 0xdeadbeef;
748c2c66affSColin Finck 	result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
749c2c66affSColin Finck 	ok(result, "expected TRUE, got %d\n", result);
750c2c66affSColin Finck 	ok(provType==dwProvType, "expected %d, got %d\n", dwProvType, provType);
751c2c66affSColin Finck 	if (pszTypeName)
752c2c66affSColin Finck 		ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName, typeName);
753c2c66affSColin Finck 	ok(typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
754c2c66affSColin Finck 
755c2c66affSColin Finck 	LocalFree(typeName);
756c2c66affSColin Finck cleanup:
757c2c66affSColin Finck 	LocalFree(pszTypeName);
758c2c66affSColin Finck }
759c2c66affSColin Finck 
FindDfltProvRegVals(DWORD dwProvType,DWORD dwFlags,LPSTR * pszProvName,DWORD * pcbProvName)760c2c66affSColin Finck static BOOL FindDfltProvRegVals(DWORD dwProvType, DWORD dwFlags, LPSTR *pszProvName, DWORD *pcbProvName)
761c2c66affSColin Finck {
762c2c66affSColin Finck 	HKEY hKey;
763c2c66affSColin Finck 	PSTR keyname;
764c2c66affSColin Finck 	PSTR ptr;
765c2c66affSColin Finck 	DWORD user = dwFlags & CRYPT_USER_DEFAULT;
766c2c66affSColin Finck 
767c2c66affSColin Finck 	LPCSTR machinestr = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
768c2c66affSColin Finck 	LPCSTR userstr = "Software\\Microsoft\\Cryptography\\Provider Type XXX";
769c2c66affSColin Finck 
770c2c66affSColin Finck 	keyname = LocalAlloc(LMEM_ZEROINIT, (user ? strlen(userstr) : strlen(machinestr)) + 1);
771c2c66affSColin Finck 	if (keyname)
772c2c66affSColin Finck 	{
773c2c66affSColin Finck 		user ? strcpy(keyname, userstr) : strcpy(keyname, machinestr);
774c2c66affSColin Finck 		ptr = keyname + strlen(keyname);
775c2c66affSColin Finck 		*(--ptr) = (dwProvType % 10) + '0';
776c2c66affSColin Finck 		*(--ptr) = ((dwProvType / 10) % 10) + '0';
777c2c66affSColin Finck 		*(--ptr) = (dwProvType / 100) + '0';
778c2c66affSColin Finck 	} else
779c2c66affSColin Finck 		return FALSE;
780c2c66affSColin Finck 
781c2c66affSColin Finck 	if (RegOpenKeyA((dwFlags & CRYPT_USER_DEFAULT) ?  HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey))
782c2c66affSColin Finck 	{
783c2c66affSColin Finck 		LocalFree(keyname);
784c2c66affSColin Finck 		return FALSE;
785c2c66affSColin Finck 	}
786c2c66affSColin Finck 	LocalFree(keyname);
787c2c66affSColin Finck 
788c2c66affSColin Finck 	if (RegQueryValueExA(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
789c2c66affSColin Finck 	{
790c2c66affSColin Finck 		if (GetLastError() != ERROR_MORE_DATA)
791c2c66affSColin Finck 			SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
792c2c66affSColin Finck 		return FALSE;
793c2c66affSColin Finck 	}
794c2c66affSColin Finck 
795c2c66affSColin Finck 	if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))
796c2c66affSColin Finck 		return FALSE;
797c2c66affSColin Finck 
798c2c66affSColin Finck 	if (RegQueryValueExA(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
799c2c66affSColin Finck 	{
800c2c66affSColin Finck 		if (GetLastError() != ERROR_MORE_DATA)
801c2c66affSColin Finck 			SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
802c2c66affSColin Finck 		return FALSE;
803c2c66affSColin Finck 	}
804c2c66affSColin Finck 
805c2c66affSColin Finck 	RegCloseKey(hKey);
806c2c66affSColin Finck 
807c2c66affSColin Finck 	return TRUE;
808c2c66affSColin Finck }
809c2c66affSColin Finck 
test_get_default_provider(void)810c2c66affSColin Finck static void test_get_default_provider(void)
811c2c66affSColin Finck {
812c2c66affSColin Finck 	/* expected results */
813c2c66affSColin Finck 	DWORD dwProvType = PROV_RSA_FULL;
814c2c66affSColin Finck 	DWORD dwFlags = CRYPT_MACHINE_DEFAULT;
815c2c66affSColin Finck 	LPSTR pszProvName = NULL;
816c2c66affSColin Finck 	DWORD cbProvName;
817c2c66affSColin Finck 
818c2c66affSColin Finck 	/* actual results */
819c2c66affSColin Finck 	DWORD provType = PROV_RSA_FULL;
820c2c66affSColin Finck 	DWORD flags = CRYPT_MACHINE_DEFAULT;
821c2c66affSColin Finck 	LPSTR provName = NULL;
822c2c66affSColin Finck 	DWORD provNameSize;
823c2c66affSColin Finck 	DWORD result;
824c2c66affSColin Finck 	DWORD notNull = 5;
825c2c66affSColin Finck 
826c2c66affSColin Finck 	if(!pCryptGetDefaultProviderA)
827c2c66affSColin Finck 	{
828c2c66affSColin Finck 	    win_skip("CryptGetDefaultProviderA is not available\n");
829c2c66affSColin Finck 	    return;
830c2c66affSColin Finck 	}
831c2c66affSColin Finck 
832c2c66affSColin Finck 	if(!FindDfltProvRegVals(dwProvType, dwFlags, &pszProvName, &cbProvName))
833c2c66affSColin Finck 	{
834c2c66affSColin Finck 	    skip("Could not find default provider in registry\n");
835c2c66affSColin Finck 	    return;
836c2c66affSColin Finck 	}
837c2c66affSColin Finck 
838c2c66affSColin Finck 	/* check pdwReserved for NULL */
839c2c66affSColin Finck 	result = pCryptGetDefaultProviderA(provType, &notNull, flags, provName, &provNameSize);
840c2c66affSColin Finck 	ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
841c2c66affSColin Finck 		ERROR_INVALID_PARAMETER, GetLastError());
842c2c66affSColin Finck 
843c2c66affSColin Finck 	/* check for invalid flag */
844c2c66affSColin Finck 	flags = 0xdeadbeef;
845c2c66affSColin Finck 	result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
846c2c66affSColin Finck 	ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %d, got %d\n",
847c2c66affSColin Finck 		NTE_BAD_FLAGS, GetLastError());
848c2c66affSColin Finck 	flags = CRYPT_MACHINE_DEFAULT;
849c2c66affSColin Finck 
850c2c66affSColin Finck 	/* check for invalid prov type */
851c2c66affSColin Finck 	provType = 0xdeadbeef;
852c2c66affSColin Finck 	result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
853c2c66affSColin Finck 	ok(!result && (GetLastError() == NTE_BAD_PROV_TYPE ||
854c2c66affSColin Finck 	               GetLastError() == ERROR_INVALID_PARAMETER),
855c2c66affSColin Finck 		"expected NTE_BAD_PROV_TYPE or ERROR_INVALID_PARAMETER, got %d/%d\n",
856c2c66affSColin Finck 		result, GetLastError());
857c2c66affSColin Finck 	provType = PROV_RSA_FULL;
858c2c66affSColin Finck 
859c2c66affSColin Finck 	SetLastError(0);
860c2c66affSColin Finck 
861c2c66affSColin Finck 	/* alloc provName to half the size required
862c2c66affSColin Finck 	 * cbProvName holds the size required */
863c2c66affSColin Finck 	provNameSize = cbProvName / 2;
864c2c66affSColin Finck 	if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
865c2c66affSColin Finck 		return;
866c2c66affSColin Finck 
867c2c66affSColin Finck 	result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
868c2c66affSColin Finck 	ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
869c2c66affSColin Finck 		ERROR_MORE_DATA, GetLastError());
870c2c66affSColin Finck 
871c2c66affSColin Finck 	LocalFree(provName);
872c2c66affSColin Finck 
873c2c66affSColin Finck 	/* check expected versus actual values returned */
874c2c66affSColin Finck 	result = pCryptGetDefaultProviderA(provType, NULL, flags, NULL, &provNameSize);
875c2c66affSColin Finck 	ok(result && provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
876c2c66affSColin Finck 	provNameSize = cbProvName;
877c2c66affSColin Finck 
878c2c66affSColin Finck 	if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
879c2c66affSColin Finck 		return;
880c2c66affSColin Finck 
881c2c66affSColin Finck 	provNameSize = 0xdeadbeef;
882c2c66affSColin Finck 	result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
883c2c66affSColin Finck 	ok(result, "expected TRUE, got %d\n", result);
884c2c66affSColin Finck 	if(pszProvName)
885c2c66affSColin Finck 	    ok(!strcmp(pszProvName, provName), "expected %s, got %s\n", pszProvName, provName);
886c2c66affSColin Finck 	ok(provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
887c2c66affSColin Finck 
888c2c66affSColin Finck 	LocalFree(pszProvName);
889c2c66affSColin Finck 	LocalFree(provName);
890c2c66affSColin Finck }
891c2c66affSColin Finck 
test_set_provider_ex(void)892c2c66affSColin Finck static void test_set_provider_ex(void)
893c2c66affSColin Finck {
894c2c66affSColin Finck 	DWORD result;
895c2c66affSColin Finck 	DWORD notNull = 5;
896c2c66affSColin Finck         LPSTR curProvName = NULL;
897c2c66affSColin Finck         DWORD curlen;
898c2c66affSColin Finck 
899c2c66affSColin Finck 	/* results */
900c2c66affSColin Finck 	LPSTR pszProvName = NULL;
901c2c66affSColin Finck 	DWORD cbProvName;
902c2c66affSColin Finck 
903c2c66affSColin Finck 	if(!pCryptGetDefaultProviderA || !pCryptSetProviderExA)
904c2c66affSColin Finck 	{
905c2c66affSColin Finck 	    win_skip("CryptGetDefaultProviderA and/or CryptSetProviderExA are not available\n");
906c2c66affSColin Finck 	    return;
907c2c66affSColin Finck 	}
908c2c66affSColin Finck 
909c2c66affSColin Finck         /* store the current one */
910c2c66affSColin Finck         pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &curlen);
911c2c66affSColin Finck         if (!(curProvName = LocalAlloc(LMEM_ZEROINIT, curlen)))
912c2c66affSColin Finck             return;
913c2c66affSColin Finck         result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, curProvName, &curlen);
914c2c66affSColin Finck         ok(result, "%d\n", GetLastError());
915c2c66affSColin Finck 
916c2c66affSColin Finck 	/* check pdwReserved for NULL */
917c2c66affSColin Finck 	result = pCryptSetProviderExA(MS_DEF_PROV_A, PROV_RSA_FULL, &notNull, CRYPT_MACHINE_DEFAULT);
918c2c66affSColin Finck 	ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
919c2c66affSColin Finck 		ERROR_INVALID_PARAMETER, GetLastError());
920c2c66affSColin Finck 
921c2c66affSColin Finck 	/* remove the default provider and then set it to MS_DEF_PROV/PROV_RSA_FULL */
922c2c66affSColin Finck         SetLastError(0xdeadbeef);
923c2c66affSColin Finck 	result = pCryptSetProviderExA(MS_DEF_PROV_A, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT | CRYPT_DELETE_DEFAULT);
924c2c66affSColin Finck 	if (!result)
925c2c66affSColin Finck 	{
926c2c66affSColin Finck                 ok( GetLastError() == ERROR_ACCESS_DENIED || broken(GetLastError() == ERROR_INVALID_PARAMETER),
927c2c66affSColin Finck                     "wrong error %u\n", GetLastError() );
928c2c66affSColin Finck 		skip("Not enough rights to remove the default provider\n");
929c2c66affSColin Finck                 LocalFree(curProvName);
930c2c66affSColin Finck 		return;
931c2c66affSColin Finck 	}
932c2c66affSColin Finck 
933c2c66affSColin Finck 	result = pCryptSetProviderExA(MS_DEF_PROV_A, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
934c2c66affSColin Finck 	ok(result, "%d\n", GetLastError());
935c2c66affSColin Finck 
936c2c66affSColin Finck 	/* call CryptGetDefaultProvider to see if they match */
937c2c66affSColin Finck 	result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &cbProvName);
938c2c66affSColin Finck 	ok(result, "%d\n", GetLastError());
939c2c66affSColin Finck 	if (!(pszProvName = LocalAlloc(LMEM_ZEROINIT, cbProvName)))
940c2c66affSColin Finck 		goto reset;
941c2c66affSColin Finck 
942c2c66affSColin Finck 	result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, pszProvName, &cbProvName);
943c2c66affSColin Finck 	ok(result && !strcmp(MS_DEF_PROV_A, pszProvName), "expected %s, got %s\n", MS_DEF_PROV_A, pszProvName);
944c2c66affSColin Finck 	ok(result && cbProvName==(strlen(MS_DEF_PROV_A) + 1), "expected %i, got %d\n", (lstrlenA(MS_DEF_PROV_A) + 1), cbProvName);
945c2c66affSColin Finck 
946c2c66affSColin Finck 	LocalFree(pszProvName);
947c2c66affSColin Finck 
948c2c66affSColin Finck reset:
949c2c66affSColin Finck         /* Set the provider back to its original */
950c2c66affSColin Finck         result = pCryptSetProviderExA(curProvName, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
951c2c66affSColin Finck         ok(result, "%d\n", GetLastError());
952c2c66affSColin Finck         LocalFree(curProvName);
953c2c66affSColin Finck }
954c2c66affSColin Finck 
test_machine_guid(void)955c2c66affSColin Finck static void test_machine_guid(void)
956c2c66affSColin Finck {
957c2c66affSColin Finck    char originalGuid[40];
958c2c66affSColin Finck    LONG r;
959c2c66affSColin Finck    HKEY key;
960c2c66affSColin Finck    DWORD size;
961c2c66affSColin Finck    HCRYPTPROV hCryptProv;
962c2c66affSColin Finck    BOOL restoreGuid = FALSE, ret;
963c2c66affSColin Finck 
964c2c66affSColin Finck    r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography",
965c2c66affSColin Finck                      0, KEY_ALL_ACCESS, &key);
966c2c66affSColin Finck    if (r != ERROR_SUCCESS)
967c2c66affSColin Finck    {
968c2c66affSColin Finck        skip("couldn't open HKLM\\Software\\Microsoft\\Cryptography\n");
969c2c66affSColin Finck        return;
970c2c66affSColin Finck    }
971c2c66affSColin Finck    /* Cache existing MachineGuid, and delete it */
972c2c66affSColin Finck    size = sizeof(originalGuid);
973c2c66affSColin Finck    r = RegQueryValueExA(key, "MachineGuid", NULL, NULL, (BYTE *)originalGuid,
974c2c66affSColin Finck                         &size);
975c2c66affSColin Finck    if (r == ERROR_SUCCESS)
976c2c66affSColin Finck    {
977c2c66affSColin Finck        restoreGuid = TRUE;
978c2c66affSColin Finck        r = RegDeleteValueA(key, "MachineGuid");
979c2c66affSColin Finck        ok(!r || broken(r == ERROR_ACCESS_DENIED) /*win8*/, "RegDeleteValueA failed: %d\n", r);
980c2c66affSColin Finck        if (r == ERROR_ACCESS_DENIED)
981c2c66affSColin Finck        {
982c2c66affSColin Finck            skip("broken virtualization on HKLM\\Software\\Microsoft\\Cryptography\n");
983c2c66affSColin Finck            RegCloseKey(key);
984c2c66affSColin Finck            return;
985c2c66affSColin Finck        }
986c2c66affSColin Finck    }
987c2c66affSColin Finck    else
988c2c66affSColin Finck        ok(r == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n",
989c2c66affSColin Finck           r);
990c2c66affSColin Finck    /* Create and release a provider */
991c2c66affSColin Finck    ret = pCryptAcquireContextA(&hCryptProv, szKeySet, NULL, PROV_RSA_FULL, 0);
992c2c66affSColin Finck    ok(ret || broken(!ret && GetLastError() == NTE_KEYSET_ENTRY_BAD /* NT4 */),
993c2c66affSColin Finck       "CryptAcquireContextA failed: %08x\n", GetLastError());
994c2c66affSColin Finck    pCryptReleaseContext(hCryptProv, 0);
995c2c66affSColin Finck 
996c2c66affSColin Finck    if (restoreGuid)
997c2c66affSColin Finck        RegSetValueExA(key, "MachineGuid", 0, REG_SZ, (const BYTE *)originalGuid,
998c2c66affSColin Finck                       strlen(originalGuid)+1);
999c2c66affSColin Finck    RegCloseKey(key);
1000c2c66affSColin Finck }
1001c2c66affSColin Finck 
1002c2c66affSColin Finck #define key_length 16
1003c2c66affSColin Finck 
1004c2c66affSColin Finck static const unsigned char key[key_length] =
1005c2c66affSColin Finck     { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd,
1006c2c66affSColin Finck       0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 };
1007c2c66affSColin Finck 
test_rc2_keylen(void)1008c2c66affSColin Finck static void test_rc2_keylen(void)
1009c2c66affSColin Finck {
1010c2c66affSColin Finck     struct KeyBlob
1011c2c66affSColin Finck     {
1012c2c66affSColin Finck         BLOBHEADER header;
1013c2c66affSColin Finck         DWORD key_size;
1014c2c66affSColin Finck         BYTE key_data[2048];
1015c2c66affSColin Finck     } key_blob;
1016c2c66affSColin Finck 
1017c2c66affSColin Finck     HCRYPTPROV provider;
1018c2c66affSColin Finck     HCRYPTKEY hkey = 0;
1019c2c66affSColin Finck     BOOL ret;
1020c2c66affSColin Finck 
1021c2c66affSColin Finck     SetLastError(0xdeadbeef);
1022c2c66affSColin Finck     ret = pCryptAcquireContextA(&provider, NULL, NULL,
1023c2c66affSColin Finck                                 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1024c2c66affSColin Finck     ok(ret, "CryptAcquireContext error %u\n", GetLastError());
1025c2c66affSColin Finck     if (ret)
1026c2c66affSColin Finck     {
1027c2c66affSColin Finck         key_blob.header.bType = PLAINTEXTKEYBLOB;
1028c2c66affSColin Finck         key_blob.header.bVersion = CUR_BLOB_VERSION;
1029c2c66affSColin Finck         key_blob.header.reserved = 0;
1030c2c66affSColin Finck         key_blob.header.aiKeyAlg = CALG_RC2;
1031c2c66affSColin Finck         key_blob.key_size = sizeof(key);
1032c2c66affSColin Finck         memcpy(key_blob.key_data, key, key_length);
1033c2c66affSColin Finck 
1034c2c66affSColin Finck         /* Importing a 16-byte key works with the default provider. */
1035c2c66affSColin Finck         SetLastError(0xdeadbeef);
1036c2c66affSColin Finck         ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1037c2c66affSColin Finck                           sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1038c2c66affSColin Finck                           0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1039c2c66affSColin Finck         /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
1040c2c66affSColin Finck         ok(ret ||
1041c2c66affSColin Finck            broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1042c2c66affSColin Finck            "CryptImportKey error %08x\n", GetLastError());
1043c2c66affSColin Finck 
1044c2c66affSColin Finck         if (ret)
1045c2c66affSColin Finck             pCryptDestroyKey(hkey);
1046c2c66affSColin Finck         pCryptReleaseContext(provider, 0);
1047c2c66affSColin Finck     }
1048c2c66affSColin Finck 
1049c2c66affSColin Finck     SetLastError(0xdeadbeef);
1050c2c66affSColin Finck     ret = pCryptAcquireContextA(&provider, NULL, MS_DEF_PROV_A,
1051c2c66affSColin Finck                                 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1052c2c66affSColin Finck     ok(ret, "CryptAcquireContext error %08x\n", GetLastError());
1053c2c66affSColin Finck 
1054c2c66affSColin Finck     if (ret)
1055c2c66affSColin Finck     {
1056c2c66affSColin Finck         /* Importing a 16-byte key doesn't work with the base provider.. */
1057c2c66affSColin Finck         SetLastError(0xdeadbeef);
1058c2c66affSColin Finck         ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1059c2c66affSColin Finck                               sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1060c2c66affSColin Finck                               0, 0, &hkey);
1061c2c66affSColin Finck         ok(!ret && (GetLastError() == NTE_BAD_DATA ||
1062c2c66affSColin Finck                     GetLastError() == NTE_BAD_LEN || /* Win7 */
1063c2c66affSColin Finck                     GetLastError() == NTE_BAD_TYPE || /* W2K */
1064c2c66affSColin Finck                     GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */
1065c2c66affSColin Finck            "unexpected error %08x\n", GetLastError());
1066c2c66affSColin Finck         /* but importing an 56-bit (7-byte) key does.. */
1067c2c66affSColin Finck         key_blob.key_size = 7;
1068c2c66affSColin Finck         SetLastError(0xdeadbeef);
1069c2c66affSColin Finck         ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1070c2c66affSColin Finck                               sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1071c2c66affSColin Finck                               0, 0, &hkey);
1072c2c66affSColin Finck         ok(ret ||
1073c2c66affSColin Finck            broken(!ret && GetLastError() == NTE_BAD_TYPE) || /* W2K */
1074c2c66affSColin Finck            broken(!ret && GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */
1075c2c66affSColin Finck            "CryptAcquireContext error %08x\n", GetLastError());
1076c2c66affSColin Finck         if (ret)
1077c2c66affSColin Finck             pCryptDestroyKey(hkey);
1078c2c66affSColin Finck         /* as does importing a 16-byte key with the base provider when
1079c2c66affSColin Finck          * CRYPT_IPSEC_HMAC_KEY is specified.
1080c2c66affSColin Finck          */
1081c2c66affSColin Finck         key_blob.key_size = sizeof(key);
1082c2c66affSColin Finck         SetLastError(0xdeadbeef);
1083c2c66affSColin Finck         ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1084c2c66affSColin Finck                               sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1085c2c66affSColin Finck                               0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1086c2c66affSColin Finck         /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
1087c2c66affSColin Finck         ok(ret ||
1088c2c66affSColin Finck            broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1089c2c66affSColin Finck            "CryptImportKey error %08x\n", GetLastError());
1090c2c66affSColin Finck         if (ret)
1091c2c66affSColin Finck             pCryptDestroyKey(hkey);
1092c2c66affSColin Finck 
1093c2c66affSColin Finck         pCryptReleaseContext(provider, 0);
1094c2c66affSColin Finck     }
1095c2c66affSColin Finck 
1096c2c66affSColin Finck     key_blob.key_size = sizeof(key);
1097c2c66affSColin Finck     SetLastError(0xdeadbeef);
1098c2c66affSColin Finck     ret = pCryptAcquireContextA(&provider, NULL, NULL,
1099c2c66affSColin Finck                                 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1100c2c66affSColin Finck     ok(ret, "CryptAcquireContext error %08x\n", GetLastError());
1101c2c66affSColin Finck 
1102c2c66affSColin Finck     if (ret)
1103c2c66affSColin Finck     {
1104c2c66affSColin Finck         /* Importing a 16-byte key also works with the default provider when
1105c2c66affSColin Finck          * CRYPT_IPSEC_HMAC_KEY is specified.
1106c2c66affSColin Finck          */
1107c2c66affSColin Finck         SetLastError(0xdeadbeef);
1108c2c66affSColin Finck         ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1109c2c66affSColin Finck                               sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1110c2c66affSColin Finck                               0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1111c2c66affSColin Finck         ok(ret ||
1112c2c66affSColin Finck            broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1113c2c66affSColin Finck            "CryptImportKey error %08x\n", GetLastError());
1114c2c66affSColin Finck         if (ret)
1115c2c66affSColin Finck             pCryptDestroyKey(hkey);
1116c2c66affSColin Finck 
1117c2c66affSColin Finck         /* There is no apparent limit to the size of the input key when
1118c2c66affSColin Finck          * CRYPT_IPSEC_HMAC_KEY is specified.
1119c2c66affSColin Finck          */
1120c2c66affSColin Finck         key_blob.key_size = sizeof(key_blob.key_data);
1121c2c66affSColin Finck         SetLastError(0xdeadbeef);
1122c2c66affSColin Finck         ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1123c2c66affSColin Finck                               sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1124c2c66affSColin Finck                               0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1125c2c66affSColin Finck         ok(ret ||
1126c2c66affSColin Finck            broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1127c2c66affSColin Finck            "CryptImportKey error %08x\n", GetLastError());
1128c2c66affSColin Finck         if (ret)
1129c2c66affSColin Finck             pCryptDestroyKey(hkey);
1130c2c66affSColin Finck 
1131c2c66affSColin Finck         pCryptReleaseContext(provider, 0);
1132c2c66affSColin Finck     }
1133c2c66affSColin Finck }
1134c2c66affSColin Finck 
test_SystemFunction004(void)1135ffd1293fSEric Kohl static void test_SystemFunction004(void)
1136ffd1293fSEric Kohl {
1137ffd1293fSEric Kohl     struct ustring inData;
1138ffd1293fSEric Kohl     struct ustring keyData;
1139ffd1293fSEric Kohl     struct ustring outData;
1140ffd1293fSEric Kohl     char inString[] = "Testdata for encryption";
1141ffd1293fSEric Kohl     char keyString[] = "EncryptionKey";
1142ffd1293fSEric Kohl     unsigned char outBuffer[32];
1143ffd1293fSEric Kohl     NTSTATUS Status;
1144ffd1293fSEric Kohl #if 0
1145ffd1293fSEric Kohl     int i;
1146ffd1293fSEric Kohl #endif
1147ffd1293fSEric Kohl 
1148ffd1293fSEric Kohl     if (!pSystemFunction004)
1149ffd1293fSEric Kohl     {
1150ffd1293fSEric Kohl         win_skip("SystemFunction004 is not available\n");
1151ffd1293fSEric Kohl         return;
1152ffd1293fSEric Kohl     }
1153ffd1293fSEric Kohl 
1154ffd1293fSEric Kohl     inData.Length = strlen(inString) + 1;
1155ffd1293fSEric Kohl     inData.MaximumLength = inData.Length;
1156ffd1293fSEric Kohl     inData.Buffer = (unsigned char *)inString;
1157ffd1293fSEric Kohl 
1158ffd1293fSEric Kohl     keyData.Length = strlen(keyString) + 1;
1159ffd1293fSEric Kohl     keyData.MaximumLength = keyData.Length;
1160ffd1293fSEric Kohl     keyData.Buffer = (unsigned char *)keyString;
1161ffd1293fSEric Kohl 
1162ffd1293fSEric Kohl     outData.Length = 0;
1163ffd1293fSEric Kohl     outData.MaximumLength = 0;
1164ffd1293fSEric Kohl     outData.Buffer = NULL;
1165ffd1293fSEric Kohl 
1166ffd1293fSEric Kohl     Status = pSystemFunction004(&inData, &keyData, &outData);
1167ffd1293fSEric Kohl     ok(Status == STATUS_BUFFER_TOO_SMALL, "Expected SystemFunction004 to return STATUS_BUFFER_TOO_SMALL, got 0x%08lx\n", Status);
1168ffd1293fSEric Kohl     ok(outData.Length == 32, "Expected outData.Length to be 32, got %lu\n", outData.Length);
1169ffd1293fSEric Kohl     ok(outData.MaximumLength == 0, "Expected outData.MaximumLength to be 0, got %lu\n", outData.MaximumLength);
1170ffd1293fSEric Kohl     ok(outData.Buffer == NULL, "Expected outData.Length to be NULL, got %p\n", outData.Buffer);
1171ffd1293fSEric Kohl 
1172ffd1293fSEric Kohl     outData.Length = sizeof(outBuffer);
1173ffd1293fSEric Kohl     outData.MaximumLength = outData.Length;
1174ffd1293fSEric Kohl     outData.Buffer = outBuffer;
1175ffd1293fSEric Kohl 
1176ffd1293fSEric Kohl     Status = pSystemFunction004(&inData, &keyData, &outData);
1177ffd1293fSEric Kohl     ok(Status == STATUS_SUCCESS, "Expected SystemFunction004 to return STATUS_SUCCESS, got 0x%08lx\n", Status);
1178ffd1293fSEric Kohl     ok(outData.Length == 32, "Expected outData.Length to be 32, got %lu\n", outData.Length);
1179ffd1293fSEric Kohl     ok(outData.MaximumLength == 32, "Expected outData.MaximumLength to be 32, got %lu\n", outData.MaximumLength);
1180ffd1293fSEric Kohl     ok(outData.Buffer != NULL, "Expected outData.Buffer not to be NULL, got %p\n", outData.Buffer);
1181ffd1293fSEric Kohl #if 0
1182ffd1293fSEric Kohl     if (Status == STATUS_SUCCESS)
1183ffd1293fSEric Kohl     {
1184ffd1293fSEric Kohl          printf("outData.Buffer:\n");
1185ffd1293fSEric Kohl          for (i = 0; i < sizeof(outBuffer); i++)
1186ffd1293fSEric Kohl               printf("0x%02x ", outBuffer[i]);
1187ffd1293fSEric Kohl          printf("\n");
1188ffd1293fSEric Kohl     }
1189ffd1293fSEric Kohl #endif
1190ffd1293fSEric Kohl }
1191ffd1293fSEric Kohl 
test_SystemFunction005(void)1192ffd1293fSEric Kohl static void test_SystemFunction005(void)
1193ffd1293fSEric Kohl {
1194ffd1293fSEric Kohl     struct ustring inData;
1195ffd1293fSEric Kohl     struct ustring keyData;
1196ffd1293fSEric Kohl     struct ustring outData;
1197ffd1293fSEric Kohl     unsigned char inBuffer[32] = {0xdc, 0xff, 0x05, 0x8d, 0xaf, 0xb6, 0xe2, 0x8c, 0x4f, 0xee, 0x00, 0x06, 0xac, 0x1d, 0x56, 0xf1,
1198ffd1293fSEric Kohl                                   0x24, 0xbd, 0x17, 0xe0, 0xf6, 0xb8, 0x6d, 0x3a, 0x69, 0x5d, 0x14, 0xf9, 0x5a, 0x54, 0x93, 0xd1};
1199ffd1293fSEric Kohl     char keyString[] = "EncryptionKey";
1200ffd1293fSEric Kohl     char outBuffer[24];
1201ffd1293fSEric Kohl     NTSTATUS Status;
1202ffd1293fSEric Kohl 
1203ffd1293fSEric Kohl     if (!pSystemFunction005)
1204ffd1293fSEric Kohl     {
1205ffd1293fSEric Kohl         win_skip("SystemFunction005 is not available\n");
1206ffd1293fSEric Kohl         return;
1207ffd1293fSEric Kohl     }
1208ffd1293fSEric Kohl 
1209ffd1293fSEric Kohl     inData.Length = sizeof(inBuffer);
1210ffd1293fSEric Kohl     inData.MaximumLength = inData.Length;
1211ffd1293fSEric Kohl     inData.Buffer = inBuffer;
1212ffd1293fSEric Kohl 
1213ffd1293fSEric Kohl     keyData.Length = strlen(keyString) + 1;
1214ffd1293fSEric Kohl     keyData.MaximumLength = keyData.Length;
1215ffd1293fSEric Kohl     keyData.Buffer = (unsigned char *)keyString;
1216ffd1293fSEric Kohl 
1217ffd1293fSEric Kohl     outData.Length = 0;
1218ffd1293fSEric Kohl     outData.MaximumLength = 0;
1219ffd1293fSEric Kohl     outData.Buffer = NULL;
1220ffd1293fSEric Kohl 
1221ffd1293fSEric Kohl     Status = pSystemFunction005(&inData, &keyData, &outData);
1222ffd1293fSEric Kohl     ok(Status == STATUS_BUFFER_TOO_SMALL, "Expected SystemFunction005 to return STATUS_BUFFER_TOO_SMALL, got 0x%08lx\n", Status);
1223ffd1293fSEric Kohl     ok(outData.Length == 24, "Expected outData.Length to be 24, got %lu\n", outData.Length);
1224ffd1293fSEric Kohl     ok(outData.MaximumLength == 0, "Expected outData.MaximumLength to be 0, got %lu\n", outData.MaximumLength);
1225ffd1293fSEric Kohl     ok(outData.Buffer == NULL, "Expected outData.Buffer to be NULL, got %p\n", outData.Buffer);
1226ffd1293fSEric Kohl 
1227ffd1293fSEric Kohl     outData.Length = sizeof(outBuffer);
1228ffd1293fSEric Kohl     outData.MaximumLength = outData.Length;
1229ffd1293fSEric Kohl     outData.Buffer = (unsigned char *)outBuffer;
1230ffd1293fSEric Kohl 
1231ffd1293fSEric Kohl     Status = pSystemFunction005(&inData, &keyData, &outData);
1232ffd1293fSEric Kohl     ok(Status == STATUS_SUCCESS, "Expected SystemFunction005 to return STATUS_SUCCESS, got 0x%08lx\n", Status);
1233ffd1293fSEric Kohl     ok(outData.Length == 24, "Expected outData.Length to be 24, got %lu\n", outData.Length);
1234ffd1293fSEric Kohl     ok(outData.MaximumLength == 24, "Expected outData.MaximumLength to be 24, got %lu\n", outData.MaximumLength);
1235ffd1293fSEric Kohl     ok(outData.Buffer != NULL, "Expected outData.Buffer not to be NULL, got %p\n", outData.Buffer);
1236ffd1293fSEric Kohl #if 0
1237ffd1293fSEric Kohl     if (Status == STATUS_SUCCESS)
1238ffd1293fSEric Kohl         printf("outData.Buffer: '%s'\n", outData.Buffer);
1239ffd1293fSEric Kohl #endif
1240ffd1293fSEric Kohl }
1241ffd1293fSEric Kohl 
1242ffd1293fSEric Kohl 
test_SystemFunction036(void)1243c2c66affSColin Finck static void test_SystemFunction036(void)
1244c2c66affSColin Finck {
1245c2c66affSColin Finck     BOOL ret;
1246c2c66affSColin Finck     int test;
1247c2c66affSColin Finck 
1248c2c66affSColin Finck     if (!pSystemFunction036)
1249c2c66affSColin Finck     {
1250c2c66affSColin Finck         win_skip("SystemFunction036 is not available\n");
1251c2c66affSColin Finck         return;
1252c2c66affSColin Finck     }
1253c2c66affSColin Finck 
1254c2c66affSColin Finck     ret = pSystemFunction036(NULL, 0);
1255c2c66affSColin Finck     ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
1256c2c66affSColin Finck 
1257c2c66affSColin Finck     /* Test crashes on Windows. */
1258c2c66affSColin Finck     if (0)
1259c2c66affSColin Finck     {
1260c2c66affSColin Finck         SetLastError(0xdeadbeef);
1261c2c66affSColin Finck         ret = pSystemFunction036(NULL, 5);
1262c2c66affSColin Finck         trace("ret = %d, GetLastError() = %d\n", ret, GetLastError());
1263c2c66affSColin Finck     }
1264c2c66affSColin Finck 
1265c2c66affSColin Finck     ret = pSystemFunction036(&test, 0);
1266c2c66affSColin Finck     ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
1267c2c66affSColin Finck 
1268c2c66affSColin Finck     ret = pSystemFunction036(&test, sizeof(int));
1269c2c66affSColin Finck     ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
1270c2c66affSColin Finck }
1271c2c66affSColin Finck 
test_container_sd(void)1272c2c66affSColin Finck static void test_container_sd(void)
1273c2c66affSColin Finck {
1274c2c66affSColin Finck     HCRYPTPROV prov;
1275c2c66affSColin Finck     SECURITY_DESCRIPTOR *sd;
1276c2c66affSColin Finck     DWORD len, err;
1277c2c66affSColin Finck     BOOL ret;
1278c2c66affSColin Finck 
1279c2c66affSColin Finck     ret = CryptAcquireContextA(&prov, "winetest", "Microsoft Enhanced Cryptographic Provider v1.0",
1280c2c66affSColin Finck                                PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_NEWKEYSET);
1281c2c66affSColin Finck     ok(ret, "got %u\n", GetLastError());
1282c2c66affSColin Finck 
1283c2c66affSColin Finck     len = 0;
1284c2c66affSColin Finck     SetLastError(0xdeadbeef);
1285c2c66affSColin Finck     ret = CryptGetProvParam(prov, PP_KEYSET_SEC_DESCR, NULL, &len, OWNER_SECURITY_INFORMATION);
1286c2c66affSColin Finck     err = GetLastError();
1287c2c66affSColin Finck     ok(ret, "got %u\n", err);
1288c2c66affSColin Finck     ok(err == ERROR_INSUFFICIENT_BUFFER || broken(err == ERROR_INVALID_PARAMETER), "got %u\n", err);
1289c2c66affSColin Finck     ok(len, "expected len > 0\n");
1290c2c66affSColin Finck 
1291c2c66affSColin Finck     sd = HeapAlloc(GetProcessHeap(), 0, len);
1292c2c66affSColin Finck     ret = CryptGetProvParam(prov, PP_KEYSET_SEC_DESCR, (BYTE *)sd, &len, OWNER_SECURITY_INFORMATION);
1293c2c66affSColin Finck     ok(ret, "got %u\n", GetLastError());
1294c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, sd);
1295c2c66affSColin Finck 
1296c2c66affSColin Finck     ret = CryptReleaseContext(prov, 0);
1297c2c66affSColin Finck     ok(ret, "got %u\n", GetLastError());
1298c2c66affSColin Finck 
1299c2c66affSColin Finck     ret = CryptAcquireContextA(&prov, "winetest", "Microsoft Enhanced Cryptographic Provider v1.0",
1300c2c66affSColin Finck                                PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_DELETEKEYSET);
1301c2c66affSColin Finck     ok(ret, "got %u\n", GetLastError());
1302c2c66affSColin Finck }
1303c2c66affSColin Finck 
START_TEST(crypt)1304c2c66affSColin Finck START_TEST(crypt)
1305c2c66affSColin Finck {
1306c2c66affSColin Finck     init_function_pointers();
1307c2c66affSColin Finck     if (pCryptAcquireContextA && pCryptReleaseContext)
1308c2c66affSColin Finck     {
1309c2c66affSColin Finck 	test_rc2_keylen();
1310c2c66affSColin Finck 	init_environment();
1311c2c66affSColin Finck 	test_acquire_context();
1312c2c66affSColin Finck 	test_incorrect_api_usage();
1313c2c66affSColin Finck 	test_verify_sig();
1314c2c66affSColin Finck 	test_machine_guid();
1315c2c66affSColin Finck 	test_container_sd();
1316c2c66affSColin Finck 	clean_up_environment();
1317c2c66affSColin Finck     }
1318c2c66affSColin Finck 
1319c2c66affSColin Finck 	test_enum_providers();
1320c2c66affSColin Finck 	test_enum_provider_types();
1321c2c66affSColin Finck 	test_get_default_provider();
1322c2c66affSColin Finck 	test_set_provider_ex();
1323ffd1293fSEric Kohl 	test_SystemFunction004();
1324ffd1293fSEric Kohl 	test_SystemFunction005();
1325c2c66affSColin Finck 	test_SystemFunction036();
1326c2c66affSColin Finck }
1327