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