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