wined3d: Recognize Nvidia GT520 cards.
[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         RegCloseKey(hSubKey);
628         LocalFree(szName);
629
630 cleanup:
631         RegCloseKey(hKey);
632
633         return ret;
634 }
635
636 static void test_enum_provider_types(void)
637 {
638         /* expected values */
639         DWORD dwProvType = 0;
640         LPSTR pszTypeName = NULL;
641         DWORD cbTypeName;
642         DWORD dwTypeCount;
643
644         /* actual values */
645         DWORD index = 0;
646         DWORD provType;
647         LPSTR typeName = NULL;
648         DWORD typeNameSize;
649         DWORD typeCount;
650         DWORD result;
651         DWORD notNull = 5;
652         DWORD notZeroFlags = 5;
653
654         if(!pCryptEnumProviderTypesA)
655         {
656                 win_skip("CryptEnumProviderTypesA is not available\n");
657                 return;
658         }
659
660         if (!FindProvTypesRegVals(&index, &dwProvType, &pszTypeName, &cbTypeName, &dwTypeCount))
661         {
662                 skip("Could not find provider types in registry\n");
663                 return;
664         }
665
666         /* check pdwReserved for NULL */
667         result = pCryptEnumProviderTypesA(index, &notNull, 0, &provType, typeName, &typeNameSize);
668         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n",
669                 GetLastError());
670
671         /* check dwFlags == zero */
672         result = pCryptEnumProviderTypesA(index, NULL, notZeroFlags, &provType, typeName, &typeNameSize);
673         ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected ERROR_INVALID_PARAMETER, got %d\n",
674                 GetLastError());
675
676         /* This test fails under Win2k SP4:
677          * result = TRUE, GetLastError() == 0xdeadbeef */
678         if (0)
679         {
680                 /* alloc provider type to half the size required
681                  * cbTypeName holds the size required */
682                 typeNameSize = cbTypeName / 2;
683                 if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize)))
684                         goto cleanup;
685
686                 SetLastError(0xdeadbeef);
687                 result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
688                 ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %d/%d\n",
689                         result, GetLastError());
690
691                 LocalFree(typeName);
692         }
693
694         /* loop through the provider types to get the number of provider types 
695          * after loop ends, count should be dwTypeCount + 1 so subtract 1
696          * to get actual number of provider types */
697         typeCount = 0;
698         while(pCryptEnumProviderTypesA(typeCount++, NULL, 0, &provType, NULL, &typeNameSize))
699                 ;
700         typeCount--;
701         ok(typeCount==dwTypeCount, "expected %d, got %d\n", dwTypeCount, typeCount);
702
703         /* loop past the actual number of provider types to get the error
704          * ERROR_NO_MORE_ITEMS */
705         for (typeCount = 0; typeCount < dwTypeCount + 1; typeCount++)
706                 result = pCryptEnumProviderTypesA(typeCount, NULL, 0, &provType, NULL, &typeNameSize);
707         ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n",
708                 GetLastError());
709
710         /* check expected versus actual values returned */
711         result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, NULL, &typeNameSize);
712         ok(result && typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
713         if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize)))
714                 goto cleanup;
715
716         typeNameSize = 0xdeadbeef;
717         result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
718         ok(result, "expected TRUE, got %d\n", result);
719         ok(provType==dwProvType, "expected %d, got %d\n", dwProvType, provType);
720         if (pszTypeName)
721                 ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName, typeName);
722         ok(typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
723
724         LocalFree(typeName);
725 cleanup:
726         LocalFree(pszTypeName);
727 }
728
729 static BOOL FindDfltProvRegVals(DWORD dwProvType, DWORD dwFlags, LPSTR *pszProvName, DWORD *pcbProvName)
730 {
731         HKEY hKey;
732         PSTR keyname;
733         PSTR ptr;
734         DWORD user = dwFlags & CRYPT_USER_DEFAULT;
735         
736         LPCSTR machinestr = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
737         LPCSTR userstr = "Software\\Microsoft\\Cryptography\\Provider Type XXX";
738         
739         keyname = LocalAlloc(LMEM_ZEROINIT, (user ? strlen(userstr) : strlen(machinestr)) + 1);
740         if (keyname)
741         {
742                 user ? strcpy(keyname, userstr) : strcpy(keyname, machinestr);
743                 ptr = keyname + strlen(keyname);
744                 *(--ptr) = (dwProvType % 10) + '0';
745                 *(--ptr) = ((dwProvType / 10) % 10) + '0';
746                 *(--ptr) = (dwProvType / 100) + '0';
747         } else
748                 return FALSE;
749         
750         if (RegOpenKey((dwFlags & CRYPT_USER_DEFAULT) ?  HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey))
751         {
752                 LocalFree(keyname);
753                 return FALSE;
754         }
755         LocalFree(keyname);
756         
757         if (RegQueryValueEx(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
758         {
759                 if (GetLastError() != ERROR_MORE_DATA)
760                         SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
761                 return FALSE;
762         }
763         
764         if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))
765                 return FALSE;
766         
767         if (RegQueryValueEx(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
768         {
769                 if (GetLastError() != ERROR_MORE_DATA)
770                         SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
771                 return FALSE;
772         }
773         
774         RegCloseKey(hKey);
775         
776         return TRUE;
777 }
778
779 static void test_get_default_provider(void)
780 {
781         /* expected results */
782         DWORD dwProvType = PROV_RSA_FULL;
783         DWORD dwFlags = CRYPT_MACHINE_DEFAULT;
784         LPSTR pszProvName = NULL;
785         DWORD cbProvName;
786         
787         /* actual results */
788         DWORD provType = PROV_RSA_FULL;
789         DWORD flags = CRYPT_MACHINE_DEFAULT;
790         LPSTR provName = NULL;
791         DWORD provNameSize;
792         DWORD result;
793         DWORD notNull = 5;
794         
795         if(!pCryptGetDefaultProviderA)
796         {
797             win_skip("CryptGetDefaultProviderA is not available\n");
798             return;
799         }
800         
801         if(!FindDfltProvRegVals(dwProvType, dwFlags, &pszProvName, &cbProvName))
802         {
803             skip("Could not find default provider in registry\n");
804             return;
805         }
806         
807         /* check pdwReserved for NULL */
808         result = pCryptGetDefaultProviderA(provType, &notNull, flags, provName, &provNameSize);
809         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
810                 ERROR_INVALID_PARAMETER, GetLastError());
811         
812         /* check for invalid flag */
813         flags = 0xdeadbeef;
814         result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
815         ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %d, got %d\n",
816                 NTE_BAD_FLAGS, GetLastError());
817         flags = CRYPT_MACHINE_DEFAULT;
818         
819         /* check for invalid prov type */
820         provType = 0xdeadbeef;
821         result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
822         ok(!result && (GetLastError() == NTE_BAD_PROV_TYPE ||
823                        GetLastError() == ERROR_INVALID_PARAMETER),
824                 "expected NTE_BAD_PROV_TYPE or ERROR_INVALID_PARAMETER, got %d/%d\n",
825                 result, GetLastError());
826         provType = PROV_RSA_FULL;
827         
828         SetLastError(0);
829         
830         /* alloc provName to half the size required
831          * cbProvName holds the size required */
832         provNameSize = cbProvName / 2;
833         if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
834                 return;
835         
836         result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
837         ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
838                 ERROR_MORE_DATA, GetLastError());
839                 
840         LocalFree(provName);
841         
842         /* check expected versus actual values returned */
843         result = pCryptGetDefaultProviderA(provType, NULL, flags, NULL, &provNameSize);
844         ok(result && provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
845         provNameSize = cbProvName;
846         
847         if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
848                 return;
849         
850         provNameSize = 0xdeadbeef;
851         result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
852         ok(result, "expected TRUE, got %d\n", result);
853         if(pszProvName)
854             ok(!strcmp(pszProvName, provName), "expected %s, got %s\n", pszProvName, provName);
855         ok(provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
856
857         LocalFree(pszProvName);
858         LocalFree(provName);
859 }
860
861 static void test_set_provider_ex(void)
862 {
863         DWORD result;
864         DWORD notNull = 5;
865         LPSTR curProvName = NULL;
866         DWORD curlen;
867         
868         /* results */
869         LPSTR pszProvName = NULL;
870         DWORD cbProvName;
871         
872         if(!pCryptGetDefaultProviderA || !pCryptSetProviderExA)
873         {
874             win_skip("CryptGetDefaultProviderA and/or CryptSetProviderExA are not available\n");
875             return;
876         }
877
878         /* store the current one */
879         pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &curlen);
880         if (!(curProvName = LocalAlloc(LMEM_ZEROINIT, curlen)))
881             return;
882         result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, curProvName, &curlen);
883         ok(result, "%d\n", GetLastError());
884
885         /* check pdwReserved for NULL */
886         result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, &notNull, CRYPT_MACHINE_DEFAULT);
887         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
888                 ERROR_INVALID_PARAMETER, GetLastError());
889
890         /* remove the default provider and then set it to MS_DEF_PROV/PROV_RSA_FULL */
891         SetLastError(0xdeadbeef);
892         result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT | CRYPT_DELETE_DEFAULT);
893         if (!result)
894         {
895                 ok( GetLastError() == ERROR_ACCESS_DENIED || broken(GetLastError() == ERROR_INVALID_PARAMETER),
896                     "wrong error %u\n", GetLastError() );
897                 skip("Not enough rights to remove the default provider\n");
898                 LocalFree(curProvName);
899                 return;
900         }
901
902         result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
903         ok(result, "%d\n", GetLastError());
904         
905         /* call CryptGetDefaultProvider to see if they match */
906         result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &cbProvName);
907         ok(result, "%d\n", GetLastError());
908         if (!(pszProvName = LocalAlloc(LMEM_ZEROINIT, cbProvName)))
909                 goto reset;
910
911         result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, pszProvName, &cbProvName);
912         ok(result && !strcmp(MS_DEF_PROV, pszProvName), "expected %s, got %s\n", MS_DEF_PROV, pszProvName);
913         ok(result && cbProvName==(strlen(MS_DEF_PROV) + 1), "expected %i, got %d\n", (lstrlenA(MS_DEF_PROV) + 1), cbProvName);
914
915         LocalFree(pszProvName);
916
917 reset:
918         /* Set the provider back to it's original */
919         result = pCryptSetProviderExA(curProvName, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
920         ok(result, "%d\n", GetLastError());
921         LocalFree(curProvName);
922 }
923
924 static void test_machine_guid(void)
925 {
926    char originalGuid[40];
927    LONG r;
928    HKEY key;
929    DWORD size;
930    HCRYPTPROV hCryptProv;
931    BOOL restoreGuid = FALSE, ret;
932
933    r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography",
934                      0, KEY_ALL_ACCESS, &key);
935    if (r != ERROR_SUCCESS)
936    {
937        skip("couldn't open HKLM\\Software\\Microsoft\\Cryptography\n");
938        return;
939    }
940    /* Cache existing MachineGuid, and delete it */
941    size = sizeof(originalGuid);
942    r = RegQueryValueExA(key, "MachineGuid", NULL, NULL, (BYTE *)originalGuid,
943                         &size);
944    if (r == ERROR_SUCCESS)
945    {
946        restoreGuid = TRUE;
947        r = RegDeleteValueA(key, "MachineGuid");
948        ok(!r, "RegDeleteValueA failed: %d\n", r);
949    }
950    else
951        ok(r == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n",
952           r);
953    /* Create and release a provider */
954    ret = pCryptAcquireContextA(&hCryptProv, szKeySet, NULL, PROV_RSA_FULL, 0);
955    ok(ret || broken(!ret && GetLastError() == NTE_KEYSET_ENTRY_BAD /* NT4 */),
956       "CryptAcquireContextA failed: %08x\n", GetLastError());
957    pCryptReleaseContext(hCryptProv, 0);
958
959    if (restoreGuid)
960        RegSetValueExA(key, "MachineGuid", 0, REG_SZ, (const BYTE *)originalGuid,
961                       strlen(originalGuid)+1);
962    RegCloseKey(key);
963 }
964
965 #define key_length 16
966
967 static const unsigned char key[key_length] =
968     { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd,
969       0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 };
970
971 static void test_rc2_keylen(void)
972 {
973     struct KeyBlob
974     {
975         BLOBHEADER header;
976         DWORD key_size;
977         BYTE key_data[2048];
978     } key_blob;
979
980     HCRYPTPROV provider;
981     HCRYPTKEY hkey = 0;
982     BOOL ret;
983
984     SetLastError(0xdeadbeef);
985     ret = pCryptAcquireContextA(&provider, NULL, NULL,
986                                 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
987     ok(ret, "CryptAcquireContext error %u\n", GetLastError());
988     if (ret)
989     {
990         key_blob.header.bType = PLAINTEXTKEYBLOB;
991         key_blob.header.bVersion = CUR_BLOB_VERSION;
992         key_blob.header.reserved = 0;
993         key_blob.header.aiKeyAlg = CALG_RC2;
994         key_blob.key_size = sizeof(key);
995         memcpy(key_blob.key_data, key, key_length);
996
997         /* Importing a 16-byte key works with the default provider. */
998         SetLastError(0xdeadbeef);
999         ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1000                           sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1001                           0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1002         /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
1003         ok(ret ||
1004            broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1005            "CryptImportKey error %08x\n", GetLastError());
1006
1007         if (ret)
1008             pCryptDestroyKey(hkey);
1009         pCryptReleaseContext(provider, 0);
1010     }
1011
1012     SetLastError(0xdeadbeef);
1013     ret = pCryptAcquireContextA(&provider, NULL, MS_DEF_PROV,
1014                                 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1015     ok(ret, "CryptAcquireContext error %08x\n", GetLastError());
1016
1017     if (ret)
1018     {
1019         /* Importing a 16-byte key doesn't work with the base provider.. */
1020         SetLastError(0xdeadbeef);
1021         ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1022                               sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1023                               0, 0, &hkey);
1024         ok(!ret && (GetLastError() == NTE_BAD_DATA ||
1025                     GetLastError() == NTE_BAD_LEN || /* Win7 */
1026                     GetLastError() == NTE_BAD_TYPE || /* W2K */
1027                     GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */
1028            "unexpected error %08x\n", GetLastError());
1029         /* but importing an 56-bit (7-byte) key does.. */
1030         key_blob.key_size = 7;
1031         SetLastError(0xdeadbeef);
1032         ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1033                               sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1034                               0, 0, &hkey);
1035         ok(ret ||
1036            broken(!ret && GetLastError() == NTE_BAD_TYPE) || /* W2K */
1037            broken(!ret && GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */
1038            "CryptAcquireContext error %08x\n", GetLastError());
1039         if (ret)
1040             pCryptDestroyKey(hkey);
1041         /* as does importing a 16-byte key with the base provider when
1042          * CRYPT_IPSEC_HMAC_KEY is specified.
1043          */
1044         key_blob.key_size = sizeof(key);
1045         SetLastError(0xdeadbeef);
1046         ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1047                               sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1048                               0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1049         /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
1050         ok(ret ||
1051            broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1052            "CryptImportKey error %08x\n", GetLastError());
1053         if (ret)
1054             pCryptDestroyKey(hkey);
1055
1056         pCryptReleaseContext(provider, 0);
1057     }
1058
1059     key_blob.key_size = sizeof(key);
1060     SetLastError(0xdeadbeef);
1061     ret = pCryptAcquireContextA(&provider, NULL, NULL,
1062                                 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1063     ok(ret, "CryptAcquireContext error %08x\n", GetLastError());
1064
1065     if (ret)
1066     {
1067         /* Importing a 16-byte key also works with the default provider when
1068          * CRYPT_IPSEC_HMAC_KEY is specified.
1069          */
1070         SetLastError(0xdeadbeef);
1071         ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1072                               sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1073                               0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1074         ok(ret ||
1075            broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1076            "CryptImportKey error %08x\n", GetLastError());
1077         if (ret)
1078             pCryptDestroyKey(hkey);
1079
1080         /* There is no apparent limit to the size of the input key when
1081          * CRYPT_IPSEC_HMAC_KEY is specified.
1082          */
1083         key_blob.key_size = sizeof(key_blob.key_data);
1084         SetLastError(0xdeadbeef);
1085         ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1086                               sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1087                               0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1088         ok(ret ||
1089            broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1090            "CryptImportKey error %08x\n", GetLastError());
1091         if (ret)
1092             pCryptDestroyKey(hkey);
1093
1094         pCryptReleaseContext(provider, 0);
1095     }
1096 }
1097
1098 static void test_SystemFunction036(void)
1099 {
1100     BOOL ret;
1101     int test;
1102
1103     if (!pSystemFunction036)
1104     {
1105         win_skip("SystemFunction036 is not available\n");
1106         return;
1107     }
1108
1109     ret = pSystemFunction036(NULL, 0);
1110     ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
1111
1112     /* Test crashes on Windows. */
1113     if (0)
1114     {
1115         SetLastError(0xdeadbeef);
1116         ret = pSystemFunction036(NULL, 5);
1117         trace("ret = %d, GetLastError() = %d\n", ret, GetLastError());
1118     }
1119
1120     ret = pSystemFunction036(&test, 0);
1121     ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
1122
1123     ret = pSystemFunction036(&test, sizeof(int));
1124     ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
1125 }
1126
1127 START_TEST(crypt)
1128 {
1129     init_function_pointers();
1130     if (pCryptAcquireContextA && pCryptReleaseContext)
1131     {
1132         test_rc2_keylen();
1133         init_environment();
1134         test_acquire_context();
1135         test_incorrect_api_usage();
1136         test_verify_sig();
1137         test_machine_guid();
1138         clean_up_environment();
1139     }
1140         
1141         test_enum_providers();
1142         test_enum_provider_types();
1143         test_get_default_provider();
1144         test_set_provider_ex();
1145         test_SystemFunction036();
1146 }