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