shlwapi: Fix ASSOC_GetExecutable not to use uninitialised variable.
[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
238     result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey);
239     ok (result, "%d\n", GetLastError());
240     if (!result) return;
241
242     result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
243     ok (result, "%d\n", GetLastError());
244     if (!result) return;
245
246     result = pCryptDestroyKey(hKey2);
247     ok (result, "%d\n", GetLastError());
248
249     dwTemp = CRYPT_MODE_ECB;    
250     result = pCryptSetKeyParam(hKey2, KP_MODE, (BYTE*)&dwTemp, sizeof(DWORD));
251     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
252     
253     result = pCryptAcquireContextA(&hProv2, szBadKeySet, NULL, PROV_RSA_FULL, 
254                                    CRYPT_DELETEKEYSET);
255     ok (result, "%d\n", GetLastError());
256     if (!result) return;
257     
258     result = pCryptReleaseContext(hProv, 0);
259     ok (result, "%d\n", GetLastError());
260     if (!result) return;
261
262     result = pCryptReleaseContext(hProv, 0);
263     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
264
265     result = pCryptGenRandom(hProv, 1, &temp);
266     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
267
268 #ifdef CRASHES_ON_NT40
269     result = pCryptContextAddRef(hProv, NULL, 0);
270     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
271 #endif
272
273     result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
274     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
275
276     dwLen = 1;
277     result = pCryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, &temp, &dwLen);
278     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
279
280     dwLen = 1;
281     result = pCryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, &temp, &dwLen, 1);
282     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
283
284     result = pCryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey2);
285     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
286
287 #ifdef CRASHES_ON_NT40
288     result = pCryptDuplicateHash(hHash, NULL, 0, &hHash2);
289     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
290
291     result = pCryptDuplicateKey(hKey, NULL, 0, &hKey2);
292     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
293 #endif
294
295     dwLen = 1;
296     result = pCryptExportKey(hKey, (HCRYPTPROV)NULL, 0, 0, &temp, &dwLen);
297     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
298
299     result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
300     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
301
302     dwLen = 1;
303     result = pCryptGetHashParam(hHash, 0, &temp, &dwLen, 0);
304     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
305
306     dwLen = 1;
307     result = pCryptGetKeyParam(hKey, 0, &temp, &dwLen, 0);
308     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
309
310     dwLen = 1;
311     result = pCryptGetProvParam(hProv, 0, &temp, &dwLen, 0);
312     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
313     
314     result = pCryptGetUserKey(hProv, 0, &hKey2);
315     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
316
317     result = pCryptHashData(hHash, &temp, 1, 0);
318     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
319
320     result = pCryptHashSessionKey(hHash, hKey, 0);
321     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
322
323     result = pCryptImportKey(hProv, &temp, 1, (HCRYPTKEY)NULL, 0, &hKey2);
324     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
325
326     if (pCryptSignHashW)
327     {
328         dwLen = 1;
329         result = pCryptSignHashW(hHash, 0, NULL, 0, &temp, &dwLen);
330         ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
331             GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
332     }
333     else
334         skip("CryptSignHashW is not available\n");
335
336     result = pCryptSetKeyParam(hKey, 0, &temp, 1);
337     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
338
339     result = pCryptSetHashParam(hHash, 0, &temp, 1);
340     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
341
342     result = pCryptSetProvParam(hProv, 0, &temp, 1);
343     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
344
345     if (pCryptVerifySignatureW)
346     {
347         result = pCryptVerifySignatureW(hHash, &temp, 1, hKey, NULL, 0);
348         ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
349             GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
350     }
351     else
352         skip("CryptVerifySignatureW is not available\n");
353
354     result = pCryptDestroyHash(hHash);
355     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
356     
357     result = pCryptDestroyKey(hKey);
358     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
359 }
360
361 static const BYTE privKey[] = {
362  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
363  0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
364  0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
365  0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
366  0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
367  0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
368  0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
369  0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
370  0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
371  0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
372  0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
373  0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
374  0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
375  0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
376  0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
377  0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
378  0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
379  0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
380  0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
381  0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
382  0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
383  0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
384  0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
385  0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
386
387 static void test_verify_sig(void)
388 {
389         BOOL ret;
390         HCRYPTPROV prov;
391         HCRYPTKEY key;
392         HCRYPTHASH hash;
393         BYTE bogus[] = { 0 };
394
395         if (!pCryptVerifySignatureW)
396         {
397                 skip("CryptVerifySignatureW is not available\n");
398                 return;
399         }
400
401         SetLastError(0xdeadbeef);
402         ret = pCryptVerifySignatureW(0, NULL, 0, 0, NULL, 0);
403         if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
404         {
405                 skip("CryptVerifySignatureW is not implemented\n");
406                 return;
407         }
408         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
409          "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
410         ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL,
411          CRYPT_NEWKEYSET);
412         if (!ret && GetLastError() == NTE_EXISTS)
413                 ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL, 0);
414         ret = pCryptImportKey(prov, (LPBYTE)privKey, sizeof(privKey), 0, 0, &key);
415         ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
416         ret = pCryptCreateHash(prov, CALG_MD5, 0, 0, &hash);
417         ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
418         SetLastError(0xdeadbeef);
419         ret = pCryptVerifySignatureW(hash, NULL, 0, 0, NULL, 0);
420         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
421          "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
422         SetLastError(0xdeadbeef);
423         ret = pCryptVerifySignatureW(0, NULL, 0, key, NULL, 0);
424         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
425          "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
426         SetLastError(0xdeadbeef);
427         ret = pCryptVerifySignatureW(hash, NULL, 0, key, NULL, 0);
428         ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
429          GetLastError() == ERROR_INVALID_PARAMETER),
430          "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
431          GetLastError());
432         SetLastError(0xdeadbeef);
433         ret = pCryptVerifySignatureW(hash, NULL, sizeof(bogus), key, NULL, 0);
434         ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
435          GetLastError() == ERROR_INVALID_PARAMETER),
436          "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
437          GetLastError());
438         SetLastError(0xdeadbeef);
439         ret = pCryptVerifySignatureW(hash, bogus, 0, key, NULL, 0);
440         ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
441          "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
442         SetLastError(0xdeadbeef);
443         ret = pCryptVerifySignatureW(hash, bogus, sizeof(bogus), key, NULL, 0);
444         ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
445          "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
446         pCryptDestroyKey(key);
447         pCryptDestroyHash(hash);
448         pCryptReleaseContext(prov, 0);
449 }
450
451 static BOOL FindProvRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszProvName, 
452                             DWORD *pcbProvName, DWORD *pdwProvCount)
453 {
454         HKEY hKey;
455         HKEY subkey;
456         DWORD size = sizeof(DWORD);
457         
458         if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider", &hKey))
459                 return FALSE;
460         
461         RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwProvCount, pcbProvName, 
462                                  NULL, NULL, NULL, NULL, NULL, NULL);
463         (*pcbProvName)++;
464         
465         if (!(*pszProvName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbProvName))))
466                 return FALSE;
467         
468         RegEnumKeyEx(hKey, dwIndex, *pszProvName, pcbProvName, NULL, NULL, NULL, NULL);
469         (*pcbProvName)++;
470
471         RegOpenKey(hKey, *pszProvName, &subkey);
472         RegQueryValueEx(subkey, "Type", NULL, NULL, (LPBYTE)pdwProvType, &size);
473         
474         RegCloseKey(subkey);
475         RegCloseKey(hKey);
476         
477         return TRUE;
478 }
479
480 static void test_enum_providers(void)
481 {
482         /* expected results */
483         CHAR *pszProvName = NULL;
484         DWORD cbName;
485         DWORD dwType;
486         DWORD provCount;
487         DWORD dwIndex = 0;
488         
489         /* actual results */
490         CHAR *provider = NULL;
491         DWORD providerLen;
492         DWORD type;
493         DWORD count;
494         DWORD result;
495         DWORD notNull = 5;
496         DWORD notZeroFlags = 5;
497         
498         if(!pCryptEnumProvidersA)
499         {
500             skip("CryptEnumProvidersA is not available\n");
501             return;
502         }
503         
504         if (!FindProvRegVals(dwIndex, &dwType, &pszProvName, &cbName, &provCount))
505         {
506             skip("Could not find providers in registry\n");
507             return;
508         }
509         
510         /* check pdwReserved flag for NULL */
511         result = pCryptEnumProvidersA(dwIndex, &notNull, 0, &type, NULL, &providerLen);
512         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
513         
514         /* check dwFlags == 0 */
515         result = pCryptEnumProvidersA(dwIndex, NULL, notZeroFlags, &type, NULL, &providerLen);
516         ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d\n", GetLastError());
517         
518         /* alloc provider to half the size required
519          * cbName holds the size required */
520         providerLen = cbName / 2;
521         if (!(provider = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, providerLen))))
522                 return;
523
524         result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
525         ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
526                 ERROR_MORE_DATA, GetLastError());
527
528         LocalFree(provider);
529
530         /* loop through the providers to get the number of providers 
531          * after loop ends, count should be provCount + 1 so subtract 1
532          * to get actual number of providers */
533         count = 0;
534         while(pCryptEnumProvidersA(count++, NULL, 0, &type, NULL, &providerLen))
535                 ;
536         count--;
537         ok(count==provCount, "expected %i, got %i\n", (int)provCount, (int)count);
538         
539         /* loop past the actual number of providers to get the error
540          * ERROR_NO_MORE_ITEMS */
541         for (count = 0; count < provCount + 1; count++)
542                 result = pCryptEnumProvidersA(count, NULL, 0, &type, NULL, &providerLen);
543         ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %d\n", 
544                         ERROR_NO_MORE_ITEMS, GetLastError());
545         
546         /* check expected versus actual values returned */
547         result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, NULL, &providerLen);
548         ok(result && providerLen==cbName, "expected %i, got %i\n", (int)cbName, (int)providerLen);
549         if (!(provider = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, providerLen))))
550                 return;
551                 
552         providerLen = 0xdeadbeef;
553         result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
554         ok(result, "expected TRUE, got %d\n", result);
555         ok(type==dwType, "expected %d, got %d\n", dwType, type);
556         if (pszProvName)
557             ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
558         ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);
559
560         LocalFree(provider);
561 }
562
563 static BOOL FindProvTypesRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszTypeName, 
564                                  DWORD *pcbTypeName, DWORD *pdwTypeCount)
565 {
566         HKEY hKey;
567         HKEY hSubKey;
568         PSTR ch;
569         
570         if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey))
571                 return FALSE;
572         
573         if (RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwTypeCount, pcbTypeName, NULL,
574                         NULL, NULL, NULL, NULL, NULL))
575             return FALSE;
576         (*pcbTypeName)++;
577         
578         if (!(*pszTypeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbTypeName))))
579                 return FALSE;
580         
581         if (RegEnumKeyEx(hKey, dwIndex, *pszTypeName, pcbTypeName, NULL, NULL, NULL, NULL))
582             return FALSE;
583         (*pcbTypeName)++;
584         ch = *pszTypeName + strlen(*pszTypeName);
585         /* Convert "Type 000" to 0, etc/ */
586         *pdwProvType = *(--ch) - '0';
587         *pdwProvType += (*(--ch) - '0') * 10;
588         *pdwProvType += (*(--ch) - '0') * 100;
589         
590         if (RegOpenKey(hKey, *pszTypeName, &hSubKey))
591             return FALSE;
592         
593         if (RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, NULL, pcbTypeName))
594             return FALSE;
595
596         if (!(*pszTypeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbTypeName))))
597                 return FALSE;
598         
599         if (RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, (LPBYTE)*pszTypeName, pcbTypeName))
600             return FALSE;
601         
602         RegCloseKey(hSubKey);
603         RegCloseKey(hKey);
604         
605         return TRUE;
606 }
607
608 static void test_enum_provider_types(void)
609 {
610         /* expected values */
611         DWORD dwProvType;
612         LPSTR pszTypeName = NULL;
613         DWORD cbTypeName;
614         DWORD dwTypeCount;
615         
616         /* actual values */
617         DWORD index = 0;
618         DWORD provType;
619         LPSTR typeName = NULL;
620         DWORD typeNameSize;
621         DWORD typeCount;
622         DWORD result;
623         DWORD notNull = 5;
624         DWORD notZeroFlags = 5;
625         
626         if(!pCryptEnumProviderTypesA)
627         {
628             skip("CryptEnumProviderTypesA is not available\n");
629             return;
630         }
631         
632         if (!FindProvTypesRegVals(index, &dwProvType, &pszTypeName, &cbTypeName, &dwTypeCount))
633         {
634             skip("Could not find provider types in registry\n");
635             return;
636         }
637         
638         /* check pdwReserved for NULL */
639         result = pCryptEnumProviderTypesA(index, &notNull, 0, &provType, typeName, &typeNameSize);
640         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n", 
641                 ERROR_INVALID_PARAMETER, GetLastError());
642         
643         /* check dwFlags == zero */
644         result = pCryptEnumProviderTypesA(index, NULL, notZeroFlags, &provType, typeName, &typeNameSize);
645         ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %i, got %d\n",
646                 ERROR_INVALID_PARAMETER, GetLastError());
647         
648         /* alloc provider type to half the size required
649          * cbTypeName holds the size required */
650         typeNameSize = cbTypeName / 2;
651         if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))
652                 return;
653
654         /* This test fails under Win2k SP4:
655            result = TRUE, GetLastError() == 0xdeadbeef
656         SetLastError(0xdeadbeef);
657         result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
658         ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %d/%08lx\n",
659                 result, GetLastError());
660         */
661         
662         LocalFree(typeName);
663         
664         /* loop through the provider types to get the number of provider types 
665          * after loop ends, count should be dwTypeCount + 1 so subtract 1
666          * to get actual number of provider types */
667         typeCount = 0;
668         while(pCryptEnumProviderTypesA(typeCount++, NULL, 0, &provType, NULL, &typeNameSize))
669                 ;
670         typeCount--;
671         ok(typeCount==dwTypeCount, "expected %d, got %d\n", dwTypeCount, typeCount);
672         
673         /* loop past the actual number of provider types to get the error
674          * ERROR_NO_MORE_ITEMS */
675         for (typeCount = 0; typeCount < dwTypeCount + 1; typeCount++)
676                 result = pCryptEnumProviderTypesA(typeCount, NULL, 0, &provType, NULL, &typeNameSize);
677         ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %d\n", 
678                         ERROR_NO_MORE_ITEMS, GetLastError());
679         
680
681         /* check expected versus actual values returned */
682         result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, NULL, &typeNameSize);
683         ok(result && typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
684         if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))
685                 return;
686                 
687         typeNameSize = 0xdeadbeef;
688         result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
689         ok(result, "expected TRUE, got %d\n", result);
690         ok(provType==dwProvType, "expected %d, got %d\n", dwProvType, provType);
691         if (pszTypeName)
692             ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName, typeName);
693         ok(typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
694         
695         LocalFree(typeName);
696 }
697
698 static BOOL FindDfltProvRegVals(DWORD dwProvType, DWORD dwFlags, LPSTR *pszProvName, DWORD *pcbProvName)
699 {
700         HKEY hKey;
701         PSTR keyname;
702         PSTR ptr;
703         DWORD user = dwFlags & CRYPT_USER_DEFAULT;
704         
705         LPCSTR machinestr = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
706         LPCSTR userstr = "Software\\Microsoft\\Cryptography\\Provider Type XXX";
707         
708         keyname = LocalAlloc(LMEM_ZEROINIT, (user ? strlen(userstr) : strlen(machinestr)) + 1);
709         if (keyname)
710         {
711                 user ? strcpy(keyname, userstr) : strcpy(keyname, machinestr);
712                 ptr = keyname + strlen(keyname);
713                 *(--ptr) = (dwProvType % 10) + '0';
714                 *(--ptr) = ((dwProvType / 10) % 10) + '0';
715                 *(--ptr) = (dwProvType / 100) + '0';
716         } else
717                 return FALSE;
718         
719         if (RegOpenKey((dwFlags & CRYPT_USER_DEFAULT) ?  HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey))
720         {
721                 LocalFree(keyname);
722                 return FALSE;
723         }
724         LocalFree(keyname);
725         
726         if (RegQueryValueEx(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
727         {
728                 if (GetLastError() != ERROR_MORE_DATA)
729                         SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
730                 return FALSE;
731         }
732         
733         if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))
734                 return FALSE;
735         
736         if (RegQueryValueEx(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
737         {
738                 if (GetLastError() != ERROR_MORE_DATA)
739                         SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
740                 return FALSE;
741         }
742         
743         RegCloseKey(hKey);
744         
745         return TRUE;
746 }
747
748 static void test_get_default_provider(void)
749 {
750         /* expected results */
751         DWORD dwProvType = PROV_RSA_FULL;
752         DWORD dwFlags = CRYPT_MACHINE_DEFAULT;
753         LPSTR pszProvName = NULL;
754         DWORD cbProvName;
755         
756         /* actual results */
757         DWORD provType = PROV_RSA_FULL;
758         DWORD flags = CRYPT_MACHINE_DEFAULT;
759         LPSTR provName = NULL;
760         DWORD provNameSize;
761         DWORD result;
762         DWORD notNull = 5;
763         
764         if(!pCryptGetDefaultProviderA)
765         {
766             skip("CryptGetDefaultProviderA is not available\n");
767             return;
768         }
769         
770         if(!FindDfltProvRegVals(dwProvType, dwFlags, &pszProvName, &cbProvName))
771         {
772             skip("Could not find default provider in registry\n");
773             return;
774         }
775         
776         /* check pdwReserved for NULL */
777         result = pCryptGetDefaultProviderA(provType, &notNull, flags, provName, &provNameSize);
778         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
779                 ERROR_INVALID_PARAMETER, GetLastError());
780         
781         /* check for invalid flag */
782         flags = 0xdeadbeef;
783         result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
784         ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %d, got %d\n",
785                 NTE_BAD_FLAGS, GetLastError());
786         flags = CRYPT_MACHINE_DEFAULT;
787         
788         /* check for invalid prov type */
789         provType = 0xdeadbeef;
790         result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
791         ok(!result && (GetLastError() == NTE_BAD_PROV_TYPE ||
792                        GetLastError() == ERROR_INVALID_PARAMETER),
793                 "expected NTE_BAD_PROV_TYPE or ERROR_INVALID_PARAMETER, got %d/%d\n",
794                 result, GetLastError());
795         provType = PROV_RSA_FULL;
796         
797         SetLastError(0);
798         
799         /* alloc provName to half the size required
800          * cbProvName holds the size required */
801         provNameSize = cbProvName / 2;
802         if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
803                 return;
804         
805         result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
806         ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
807                 ERROR_MORE_DATA, GetLastError());
808                 
809         LocalFree(provName);
810         
811         /* check expected versus actual values returned */
812         result = pCryptGetDefaultProviderA(provType, NULL, flags, NULL, &provNameSize);
813         ok(result && provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
814         provNameSize = cbProvName;
815         
816         if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
817                 return;
818         
819         provNameSize = 0xdeadbeef;
820         result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
821         ok(result, "expected TRUE, got %d\n", result);
822         if(pszProvName)
823             ok(!strcmp(pszProvName, provName), "expected %s, got %s\n", pszProvName, provName);
824         ok(provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
825
826         LocalFree(provName);
827 }
828
829 static void test_set_provider_ex(void)
830 {
831         DWORD result;
832         DWORD notNull = 5;
833         
834         /* results */
835         LPSTR pszProvName = NULL;
836         DWORD cbProvName;
837         
838         if(!pCryptGetDefaultProviderA || !pCryptSetProviderExA)
839         {
840             skip("CryptGetDefaultProviderA and/or CryptSetProviderExA are not available\n");
841             return;
842         }
843
844         /* check pdwReserved for NULL */
845         result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, &notNull, CRYPT_MACHINE_DEFAULT);
846         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
847                 ERROR_INVALID_PARAMETER, GetLastError());
848
849         /* remove the default provider and then set it to MS_DEF_PROV/PROV_RSA_FULL */
850         SetLastError(0xdeadbeef);
851         result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT | CRYPT_DELETE_DEFAULT);
852         if (!result && (GetLastError() == ERROR_ACCESS_DENIED))
853         {
854                 skip("Not enough rights to remove the default provider\n");
855                 return;
856         }
857         ok(result, "%d\n", GetLastError());
858
859         result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
860         ok(result, "%d\n", GetLastError());
861         
862         /* call CryptGetDefaultProvider to see if they match */
863         result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &cbProvName);
864         if (!(pszProvName = LocalAlloc(LMEM_ZEROINIT, cbProvName)))
865                 return;
866
867         result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, pszProvName, &cbProvName);
868         ok(result && !strcmp(MS_DEF_PROV, pszProvName), "expected %s, got %s\n", MS_DEF_PROV, pszProvName);
869         ok(result && cbProvName==(strlen(MS_DEF_PROV) + 1), "expected %i, got %d\n", (lstrlenA(MS_DEF_PROV) + 1), cbProvName);
870
871         LocalFree(pszProvName);
872 }
873
874 static void test_machine_guid(void)
875 {
876    char originalGuid[40];
877    LONG r;
878    HKEY key;
879    DWORD size;
880    HCRYPTPROV hCryptProv;
881    BOOL restoreGuid = FALSE, ret;
882
883    r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography",
884                      0, KEY_ALL_ACCESS, &key);
885    if (r != ERROR_SUCCESS)
886    {
887        skip("couldn't open HKLM\\Software\\Microsoft\\Cryptography\n");
888        return;
889    }
890    /* Cache existing MachineGuid, and delete it */
891    size = sizeof(originalGuid);
892    r = RegQueryValueExA(key, "MachineGuid", NULL, NULL, (BYTE *)originalGuid,
893                         &size);
894    if (r == ERROR_SUCCESS)
895    {
896        restoreGuid = TRUE;
897        r = RegDeleteValueA(key, "MachineGuid");
898        ok(!r, "RegDeleteValueA failed: %d\n", r);
899    }
900    else
901        ok(r == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n",
902           r);
903    /* Create and release a provider */
904    ret = pCryptAcquireContextA(&hCryptProv, szKeySet, NULL, PROV_RSA_FULL, 0);
905    ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
906    pCryptReleaseContext(hCryptProv, 0);
907
908    if (restoreGuid)
909        RegSetValueExA(key, "MachineGuid", 0, REG_SZ, (const BYTE *)originalGuid,
910                       strlen(originalGuid)+1);
911    RegCloseKey(key);
912 }
913
914 START_TEST(crypt)
915 {
916         init_function_pointers();
917         if(pCryptAcquireContextA && pCryptReleaseContext) {
918         init_environment();
919         test_acquire_context();
920         test_incorrect_api_usage();
921         test_verify_sig();
922         test_machine_guid();
923         clean_up_environment();
924         }
925         
926         test_enum_providers();
927         test_enum_provider_types();
928         test_get_default_provider();
929         test_set_provider_ex();
930 }