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