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