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