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