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