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