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