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