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