mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / advapi32 / tests / crypt.c
blob6df47cd626b475af5f836112532162c8b072e592
1 /*
2 * Unit tests for crypt functions
4 * Copyright (c) 2004 Michael Jung
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.
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.
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
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wincrypt.h"
26 #include "winerror.h"
27 #include "winreg.h"
29 #include "wine/test.h"
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
37 static BOOL (WINAPI *pCryptEnumProviderTypesA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*);
38 static BOOL (WINAPI *pCryptEnumProvidersA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*);
39 static BOOL (WINAPI *pCryptGetDefaultProviderA)(DWORD, DWORD*, DWORD, LPSTR, DWORD*);
40 static BOOL (WINAPI *pCryptSetProviderExA)(LPCSTR, DWORD, DWORD*, DWORD);
41 static BOOL (WINAPI *pCryptGenRandom)(HCRYPTPROV, DWORD, BYTE*);
42 static BOOL (WINAPI *pCryptDuplicateHash)(HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
43 static BOOL (WINAPI *pCryptHashSessionKey)(HCRYPTHASH, HCRYPTKEY, DWORD);
44 static BOOL (WINAPI *pCryptSignHashW)(HCRYPTHASH, DWORD, LPCWSTR, DWORD, BYTE*, DWORD*);
45 static BOOL (WINAPI *pCryptVerifySignatureW)(HCRYPTHASH, BYTE*, DWORD, HCRYPTKEY, LPCWSTR, DWORD);
46 static BOOLEAN (WINAPI *pSystemFunction036)(PVOID, ULONG);
48 static void init_function_pointers(void)
50 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
52 pCryptEnumProviderTypesA = (void*)GetProcAddress(hadvapi32, "CryptEnumProviderTypesA");
53 pCryptEnumProvidersA = (void*)GetProcAddress(hadvapi32, "CryptEnumProvidersA");
54 pCryptGetDefaultProviderA = (void*)GetProcAddress(hadvapi32, "CryptGetDefaultProviderA");
55 pCryptSetProviderExA = (void*)GetProcAddress(hadvapi32, "CryptSetProviderExA");
56 pCryptGenRandom = (void*)GetProcAddress(hadvapi32, "CryptGenRandom");
57 pCryptDuplicateHash = (void*)GetProcAddress(hadvapi32, "CryptDuplicateHash");
58 pCryptHashSessionKey = (void*)GetProcAddress(hadvapi32, "CryptHashSessionKey");
59 pCryptSignHashW = (void*)GetProcAddress(hadvapi32, "CryptSignHashW");
60 pCryptVerifySignatureW = (void*)GetProcAddress(hadvapi32, "CryptVerifySignatureW");
61 pSystemFunction036 = (void*)GetProcAddress(hadvapi32, "SystemFunction036");
64 static void init_environment(void)
66 HCRYPTPROV hProv;
67 BOOL ret;
69 /* Ensure that container "wine_test_keyset" does exist */
70 if (!CryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
72 CryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_NEWKEYSET);
74 ret = CryptReleaseContext(hProv, 0);
75 ok(ret, "got %u\n", GetLastError());
77 /* Ensure that container "wine_test_keyset" does exist in default PROV_RSA_FULL type provider */
78 if (!CryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))
80 CryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET);
82 ret = CryptReleaseContext(hProv, 0);
83 ok(ret, "got %u\n", GetLastError());
85 /* Ensure that container "wine_test_bad_keyset" does not exist. */
86 if (CryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
88 ret = CryptReleaseContext(hProv, 0);
89 ok(ret, "got %u\n", GetLastError());
91 CryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
95 static void clean_up_environment(void)
97 HCRYPTPROV hProv;
98 BOOL ret;
100 /* Remove container "wine_test_keyset" */
101 if (CryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
103 ret = CryptReleaseContext(hProv, 0);
104 ok(ret, "got %u\n", GetLastError());
106 CryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
109 /* Remove container "wine_test_keyset" from default PROV_RSA_FULL type provider */
110 if (CryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))
112 ret = CryptReleaseContext(hProv, 0);
113 ok(ret, "got %u\n", GetLastError());
115 CryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
118 /* Remove container "wine_test_bad_keyset" */
119 if (CryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
121 ret = CryptReleaseContext(hProv, 0);
122 ok(ret, "got %u\n", GetLastError());
124 CryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
128 static void test_CryptReleaseContext(void)
130 BOOL ret;
131 HCRYPTPROV prov;
133 /* TODO: Add cases for ERROR_BUSY, ERROR_INVALID_HANDLE and NTE_BAD_UID */
135 /* NULL provider */
137 SetLastError(0xdeadbeef);
138 ret = CryptReleaseContext(0, 0);
139 ok(!ret, "CryptReleaseContext succeeded unexpectedly\n");
140 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
142 SetLastError(0xdeadbeef);
143 ret = CryptReleaseContext(0, ~0);
144 ok(!ret, "CryptReleaseContext succeeded unexpectedly\n");
145 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
147 /* Additional refcount */
149 ret = CryptAcquireContextA(&prov, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
150 ok(ret, "got %u\n", GetLastError());
152 ret = CryptContextAddRef(prov, NULL, 0);
153 ok(ret, "got %u\n", GetLastError());
155 ret = CryptContextAddRef(0, NULL, 0);
156 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
157 ret = CryptContextAddRef(0xdeadbeef, NULL, 0);
158 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
160 ret = CryptReleaseContext(prov, 0);
161 ok(ret, "got %u\n", GetLastError());
163 /* Nonzero flags, which allow release nonetheless */
165 SetLastError(0xdeadbeef);
166 ret = CryptReleaseContext(prov, ~0);
167 ok(!ret, "CryptReleaseContext succeeded unexpectedly\n");
168 ok(GetLastError() == NTE_BAD_FLAGS, "got %u\n", GetLastError());
170 /* Obsolete provider */
172 SetLastError(0xdeadbeef);
173 ret = CryptReleaseContext(prov, 0);
174 ok(!ret, "CryptReleaseContext succeeded unexpectedly\n");
175 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
177 SetLastError(0xdeadbeef);
178 ret = CryptReleaseContext(prov, ~0);
179 ok(!ret, "CryptReleaseContext succeeded unexpectedly\n");
180 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
183 static void test_acquire_context(void)
185 BOOL result;
186 HCRYPTPROV hProv;
187 DWORD GLE;
189 /* Provoke all kinds of error conditions (which are easy to provoke).
190 * The order of the error tests seems to match Windows XP's rsaenh.dll CSP,
191 * but since this is likely to change between CSP versions, we don't check
192 * this. Please don't change the order of tests. */
193 result = CryptAcquireContextA(&hProv, NULL, NULL, 0, 0);
194 ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError());
196 result = CryptAcquireContextA(&hProv, NULL, NULL, 1000, 0);
197 ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError());
199 result = CryptAcquireContextA(&hProv, NULL, NULL, NON_DEF_PROV_TYPE, 0);
200 ok(!result && GetLastError()==NTE_PROV_TYPE_NOT_DEF, "%d\n", GetLastError());
202 result = CryptAcquireContextA(&hProv, szKeySet, szNonExistentProv, PROV_RSA_FULL, 0);
203 ok(!result && GetLastError()==NTE_KEYSET_NOT_DEF, "%d\n", GetLastError());
205 result = CryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, NON_DEF_PROV_TYPE, 0);
206 ok(!result && GetLastError()==NTE_PROV_TYPE_NO_MATCH, "%d\n", GetLastError());
209 if (0)
211 /* This test fails under Win2k SP4:
212 result = TRUE, GetLastError() == ERROR_INVALID_PARAMETER */
213 SetLastError(0xdeadbeef);
214 result = CryptAcquireContextA(NULL, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
215 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d/%d\n", result, GetLastError());
218 /* Last not least, try to really acquire a context. */
219 hProv = 0;
220 SetLastError(0xdeadbeef);
221 result = CryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
222 GLE = GetLastError();
223 ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND ||
224 GLE == ERROR_SUCCESS ||
225 GLE == ERROR_RING2_STACK_IN_USE ||
226 GLE == NTE_FAIL ||
227 GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GLE);
229 if (hProv)
231 result = CryptReleaseContext(hProv, 0);
232 ok(result, "got %u\n", GetLastError());
235 /* Try again, witch an empty ("\0") szProvider parameter */
236 hProv = 0;
237 SetLastError(0xdeadbeef);
238 result = CryptAcquireContextA(&hProv, szKeySet, "", PROV_RSA_FULL, 0);
239 GLE = GetLastError();
240 ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND ||
241 GLE == ERROR_SUCCESS ||
242 GLE == ERROR_RING2_STACK_IN_USE ||
243 GLE == NTE_FAIL ||
244 GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GetLastError());
246 if (hProv)
248 result = CryptReleaseContext(hProv, 0);
249 ok(result, "got %u\n", GetLastError());
253 static void test_incorrect_api_usage(void)
255 BOOL result;
256 HCRYPTPROV hProv, hProv2;
257 HCRYPTHASH hHash, hHash2;
258 HCRYPTKEY hKey, hKey2;
259 BYTE temp;
260 DWORD dwLen, dwTemp;
262 /* This is to document incorrect api usage in the
263 * "Uru - Ages beyond Myst Demo" installer as reported by Paul Vriens.
265 * The installer destroys a hash object after having released the context
266 * with which the hash was created. This is not allowed according to MSDN,
267 * since CryptReleaseContext destroys all hash and key objects belonging to
268 * the respective context. However, while wine used to crash, Windows is more
269 * robust here and returns an ERROR_INVALID_PARAMETER code.
272 result = CryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv,
273 PROV_RSA_FULL, CRYPT_NEWKEYSET);
274 ok (result, "%08x\n", GetLastError());
275 if (!result) return;
277 /* Looks like native handles are just pointers. */
278 ok(!!*(void **)hProv, "Got zero *(void **)hProv.\n");
280 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
281 ok (result, "%d\n", GetLastError());
282 if (!result) return;
284 result = CryptDeriveKey(0, CALG_RC4, hHash, 0, &hKey2);
285 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
287 result = CryptDeriveKey(hProv, CALG_RC4, 0, 0, &hKey2);
288 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
290 result = CryptHashData(0, &temp, 1, 0);
291 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
293 result = CryptGenKey(hProv, CALG_RC4, 0, &hKey);
294 ok (result, "%d\n", GetLastError());
295 if (!result) return;
297 result = pCryptHashSessionKey(hHash, 0, 0);
298 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
300 result = pCryptHashSessionKey(0, hKey, 0);
301 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
303 result = CryptDestroyHash(hHash);
304 ok (result, "%08x\n", GetLastError());
306 result = CryptDestroyHash(0);
307 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
309 result = CryptCreateHash(0xdeadbeef, CALG_SHA, 0, 0, &hHash);
310 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
312 result = CryptCreateHash(0, CALG_SHA, 0, 0, &hHash);
313 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
315 result = CryptGenKey(0, CALG_RC4, 0, &hKey);
316 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
318 dwLen = 1;
319 result = CryptDecrypt(hKey, 0, TRUE, 0, &temp, &dwLen);
320 ok (result, "%d\n", GetLastError());
321 result = CryptDecrypt(hKey, 0xdeadbeef, TRUE, 0, &temp, &dwLen);
322 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
323 result = CryptDecrypt(0, 0, TRUE, 0, &temp, &dwLen);
324 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
325 result = CryptDecrypt(0xdeadbeef, 0, TRUE, 0, &temp, &dwLen);
326 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
328 result = CryptEncrypt(hKey, 0, TRUE, 0, &temp, &dwLen, sizeof(temp));
329 ok (result, "%d\n", GetLastError());
330 result = CryptEncrypt(hKey, 0xdeadbeef, TRUE, 0, &temp, &dwLen, sizeof(temp));
331 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
332 result = CryptEncrypt(0, 0, TRUE, 0, &temp, &dwLen, sizeof(temp));
333 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
334 result = CryptEncrypt(0xdeadbeef, 0, TRUE, 0, &temp, &dwLen, sizeof(temp));
335 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
337 dwLen = 1;
338 result = CryptExportKey(hKey, 0xdeadbeef, 0, 0, &temp, &dwLen);
339 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
341 result = CryptDestroyKey(hKey);
342 ok (result, "%d\n", GetLastError());
344 result = CryptGenKey(hProv, CALG_RC4, 0, &hKey2);
345 ok (result, "%d\n", GetLastError());
346 if (!result) return;
348 result = CryptDestroyKey(hKey2);
349 ok (result, "%d\n", GetLastError());
351 result = CryptDestroyKey(0);
352 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
354 dwTemp = CRYPT_MODE_ECB;
355 result = CryptSetKeyParam(hKey2, KP_MODE, (BYTE*)&dwTemp, sizeof(DWORD));
356 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
358 hProv2 = 0xdeadbeef;
359 result = CryptAcquireContextA(&hProv2, szBadKeySet, NULL, PROV_RSA_FULL,
360 CRYPT_DELETEKEYSET);
361 ok (result, "%d\n", GetLastError());
362 ok (hProv2 == 0, "%ld\n", hProv2);
363 if (!result) return;
365 result = CryptReleaseContext(hProv, 0);
366 ok(result, "got %u\n", GetLastError());
367 if (!result) return;
369 result = pCryptGenRandom(0, 1, &temp);
370 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
372 result = pCryptGenRandom(hProv, 1, &temp);
373 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
375 result = CryptContextAddRef(hProv, NULL, 0);
376 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
378 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
379 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
381 dwLen = 1;
382 result = CryptDecrypt(hKey, 0, TRUE, 0, &temp, &dwLen);
383 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
385 dwLen = 1;
386 result = CryptEncrypt(hKey, 0, TRUE, 0, &temp, &dwLen, 1);
387 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
389 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey2);
390 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
392 result = pCryptDuplicateHash(hHash, NULL, 0, &hHash2);
393 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
395 result = CryptDuplicateKey(hKey, NULL, 0, &hKey2);
396 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
398 dwLen = 1;
399 result = CryptExportKey(hKey, 0, 0, 0, &temp, &dwLen);
400 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
402 result = CryptGenKey(hProv, CALG_RC4, 0, &hKey2);
403 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
405 dwLen = 1;
406 result = CryptGetHashParam(hHash, 0, &temp, &dwLen, 0);
407 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
409 dwLen = 1;
410 result = CryptGetKeyParam(hKey, 0, &temp, &dwLen, 0);
411 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
413 dwLen = 1;
414 result = CryptGetProvParam(hProv, 0, &temp, &dwLen, 0);
415 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
417 result = CryptGetUserKey(0, 0, &hKey2);
418 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
420 result = CryptGetUserKey(hProv, 0, &hKey2);
421 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
423 result = CryptHashData(hHash, &temp, 1, 0);
424 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
426 result = pCryptHashSessionKey(hHash, hKey, 0);
427 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
429 result = CryptImportKey(hProv, &temp, 1, 0, 0, &hKey2);
430 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
432 if (pCryptSignHashW)
434 dwLen = 1;
435 result = pCryptSignHashW(hHash, 0, NULL, 0, &temp, &dwLen);
436 ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
437 GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
438 result = pCryptSignHashW(hHash, 0, NULL, 0, &temp, &dwLen);
439 ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
440 GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
442 else
443 win_skip("CryptSignHashW is not available\n");
445 result = CryptSetKeyParam(hKey, 0, &temp, 1);
446 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
448 result = CryptSetHashParam(hHash, 0, &temp, 1);
449 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
451 result = CryptSetProvParam(0, 0, &temp, 1);
452 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
454 result = CryptSetProvParam(hProv, 0, &temp, 1);
455 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
457 if (pCryptVerifySignatureW)
459 result = pCryptVerifySignatureW(hHash, &temp, 1, hKey, NULL, 0);
460 ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
461 GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
463 else
464 win_skip("CryptVerifySignatureW is not available\n");
466 result = CryptDestroyHash(hHash);
467 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
469 result = CryptDestroyKey(hKey);
470 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
473 static const BYTE privKey[] = {
474 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
475 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
476 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
477 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
478 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
479 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
480 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
481 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
482 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
483 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
484 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
485 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
486 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
487 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
488 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
489 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
490 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
491 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
492 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
493 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
494 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
495 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
496 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
497 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
499 static void test_verify_sig(void)
501 BOOL ret;
502 HCRYPTPROV prov;
503 HCRYPTKEY key;
504 HCRYPTHASH hash;
505 BYTE bogus[] = { 0 };
507 if (!pCryptVerifySignatureW)
509 win_skip("CryptVerifySignatureW is not available\n");
510 return;
513 SetLastError(0xdeadbeef);
514 ret = pCryptVerifySignatureW(0, NULL, 0, 0, NULL, 0);
515 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
517 win_skip("CryptVerifySignatureW is not implemented\n");
518 return;
520 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
521 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
522 ret = CryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL,
523 CRYPT_NEWKEYSET);
524 if (!ret && GetLastError() == NTE_EXISTS)
525 ret = CryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL, 0);
526 ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
527 ret = CryptImportKey(prov, (LPBYTE)privKey, sizeof(privKey), 0, 0, &key);
528 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
529 ret = CryptCreateHash(prov, CALG_MD5, 0, 0, &hash);
530 ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
531 SetLastError(0xdeadbeef);
532 ret = pCryptVerifySignatureW(hash, NULL, 0, 0, NULL, 0);
533 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
534 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
535 SetLastError(0xdeadbeef);
536 ret = pCryptVerifySignatureW(0, NULL, 0, key, NULL, 0);
537 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
538 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
539 SetLastError(0xdeadbeef);
540 ret = pCryptVerifySignatureW(hash, NULL, 0, key, NULL, 0);
541 ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
542 GetLastError() == ERROR_INVALID_PARAMETER),
543 "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
544 GetLastError());
545 SetLastError(0xdeadbeef);
546 ret = pCryptVerifySignatureW(hash, NULL, sizeof(bogus), key, NULL, 0);
547 ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
548 GetLastError() == ERROR_INVALID_PARAMETER),
549 "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
550 GetLastError());
551 SetLastError(0xdeadbeef);
552 ret = pCryptVerifySignatureW(hash, bogus, 0, key, NULL, 0);
553 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
554 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
555 SetLastError(0xdeadbeef);
556 ret = pCryptVerifySignatureW(hash, bogus, sizeof(bogus), key, NULL, 0);
557 ok(!ret &&
558 (GetLastError() == NTE_BAD_SIGNATURE ||
559 broken(GetLastError() == NTE_BAD_HASH_STATE /* older NT4 */)),
560 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
561 CryptDestroyKey(key);
562 CryptDestroyHash(hash);
564 ret = CryptReleaseContext(prov, 0);
565 ok(ret, "got %u\n", GetLastError());
568 static BOOL FindProvRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszProvName,
569 DWORD *pcbProvName, DWORD *pdwProvCount)
571 HKEY hKey;
572 HKEY subkey;
573 DWORD size = sizeof(DWORD);
575 if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider", &hKey))
576 return FALSE;
578 RegQueryInfoKeyA(hKey, NULL, NULL, NULL, pdwProvCount, pcbProvName,
579 NULL, NULL, NULL, NULL, NULL, NULL);
580 (*pcbProvName)++;
582 if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))
583 return FALSE;
585 RegEnumKeyExA(hKey, dwIndex, *pszProvName, pcbProvName, NULL, NULL, NULL, NULL);
586 (*pcbProvName)++;
588 RegOpenKeyA(hKey, *pszProvName, &subkey);
589 RegQueryValueExA(subkey, "Type", NULL, NULL, (LPBYTE)pdwProvType, &size);
591 RegCloseKey(subkey);
592 RegCloseKey(hKey);
594 return TRUE;
597 static void test_enum_providers(void)
599 /* expected results */
600 CHAR *pszProvName = NULL;
601 DWORD cbName;
602 DWORD dwType;
603 DWORD provCount;
604 DWORD dwIndex = 0;
606 /* actual results */
607 CHAR *provider = NULL;
608 DWORD providerLen;
609 DWORD type;
610 DWORD count;
611 DWORD result;
612 DWORD notNull = 5;
613 DWORD notZeroFlags = 5;
615 if(!pCryptEnumProvidersA)
617 win_skip("CryptEnumProvidersA is not available\n");
618 return;
621 if (!FindProvRegVals(dwIndex, &dwType, &pszProvName, &cbName, &provCount))
623 win_skip("Could not find providers in registry\n");
624 return;
627 /* check pdwReserved flag for NULL */
628 result = pCryptEnumProvidersA(dwIndex, &notNull, 0, &type, NULL, &providerLen);
629 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
631 /* check dwFlags == 0 */
632 result = pCryptEnumProvidersA(dwIndex, NULL, notZeroFlags, &type, NULL, &providerLen);
633 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d\n", GetLastError());
635 /* alloc provider to half the size required
636 * cbName holds the size required */
637 providerLen = cbName / 2;
638 if (!(provider = LocalAlloc(LMEM_ZEROINIT, providerLen)))
639 return;
641 result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
642 ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
643 ERROR_MORE_DATA, GetLastError());
645 LocalFree(provider);
647 /* loop through the providers to get the number of providers
648 * after loop ends, count should be provCount + 1 so subtract 1
649 * to get actual number of providers */
650 count = 0;
651 while(pCryptEnumProvidersA(count++, NULL, 0, &type, NULL, &providerLen))
653 count--;
654 ok(count==provCount, "expected %i, got %i\n", (int)provCount, (int)count);
656 /* loop past the actual number of providers to get the error
657 * ERROR_NO_MORE_ITEMS */
658 for (count = 0; count < provCount + 1; count++)
659 result = pCryptEnumProvidersA(count, NULL, 0, &type, NULL, &providerLen);
660 ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %d\n",
661 ERROR_NO_MORE_ITEMS, GetLastError());
663 /* check expected versus actual values returned */
664 result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, NULL, &providerLen);
665 ok(result && providerLen==cbName, "expected %i, got %i\n", (int)cbName, (int)providerLen);
666 if (!(provider = LocalAlloc(LMEM_ZEROINIT, providerLen)))
667 return;
669 providerLen = -1;
670 result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
671 ok(result, "expected TRUE, got %d\n", result);
672 ok(type==dwType, "expected %d, got %d\n", dwType, type);
673 if (pszProvName)
674 ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
675 ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);
677 providerLen = -1000;
678 provider[0] = 0;
679 result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
680 ok(result, "expected TRUE, got %d\n", result);
681 ok(type==dwType, "expected %d, got %d\n", dwType, type);
682 if (pszProvName)
683 ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
684 ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);
686 LocalFree(pszProvName);
687 LocalFree(provider);
690 static BOOL FindProvTypesRegVals(DWORD *pdwIndex, DWORD *pdwProvType, LPSTR *pszTypeName,
691 DWORD *pcbTypeName, DWORD *pdwTypeCount)
693 HKEY hKey;
694 HKEY hSubKey;
695 PSTR ch;
696 LPSTR szName;
697 DWORD cbName;
698 BOOL ret = FALSE;
700 if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey))
701 return FALSE;
703 if (RegQueryInfoKeyA(hKey, NULL, NULL, NULL, pdwTypeCount, &cbName, NULL,
704 NULL, NULL, NULL, NULL, NULL))
705 goto cleanup;
706 cbName++;
708 if (!(szName = LocalAlloc(LMEM_ZEROINIT, cbName)))
709 goto cleanup;
711 while (!RegEnumKeyExA(hKey, *pdwIndex, szName, &cbName, NULL, NULL, NULL, NULL))
713 cbName++;
714 ch = szName + strlen(szName);
715 /* Convert "Type 000" to 0, etc/ */
716 *pdwProvType = *(--ch) - '0';
717 *pdwProvType += (*(--ch) - '0') * 10;
718 *pdwProvType += (*(--ch) - '0') * 100;
720 if (RegOpenKeyA(hKey, szName, &hSubKey))
721 break;
723 if (!RegQueryValueExA(hSubKey, "TypeName", NULL, NULL, NULL, pcbTypeName))
725 if (!(*pszTypeName = LocalAlloc(LMEM_ZEROINIT, *pcbTypeName)))
726 break;
728 if (!RegQueryValueExA(hSubKey, "TypeName", NULL, NULL, (LPBYTE)*pszTypeName, pcbTypeName))
730 ret = TRUE;
731 break;
734 LocalFree(*pszTypeName);
737 RegCloseKey(hSubKey);
739 (*pdwIndex)++;
741 RegCloseKey(hSubKey);
742 LocalFree(szName);
744 cleanup:
745 RegCloseKey(hKey);
747 return ret;
750 static void test_enum_provider_types(void)
752 /* expected values */
753 DWORD dwProvType = 0;
754 LPSTR pszTypeName = NULL;
755 DWORD cbTypeName;
756 DWORD dwTypeCount;
758 /* actual values */
759 DWORD index = 0;
760 DWORD provType;
761 LPSTR typeName = NULL;
762 DWORD typeNameSize;
763 DWORD typeCount;
764 DWORD result;
765 DWORD notNull = 5;
766 DWORD notZeroFlags = 5;
768 if(!pCryptEnumProviderTypesA)
770 win_skip("CryptEnumProviderTypesA is not available\n");
771 return;
774 if (!FindProvTypesRegVals(&index, &dwProvType, &pszTypeName, &cbTypeName, &dwTypeCount))
776 skip("Could not find provider types in registry\n");
777 return;
780 /* check pdwReserved for NULL */
781 result = pCryptEnumProviderTypesA(index, &notNull, 0, &provType, typeName, &typeNameSize);
782 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n",
783 GetLastError());
785 /* check dwFlags == zero */
786 result = pCryptEnumProviderTypesA(index, NULL, notZeroFlags, &provType, typeName, &typeNameSize);
787 ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected ERROR_INVALID_PARAMETER, got %d\n",
788 GetLastError());
790 /* This test fails under Win2k SP4:
791 * result = TRUE, GetLastError() == 0xdeadbeef */
792 if (0)
794 /* alloc provider type to half the size required
795 * cbTypeName holds the size required */
796 typeNameSize = cbTypeName / 2;
797 if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize)))
798 goto cleanup;
800 SetLastError(0xdeadbeef);
801 result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
802 ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %d/%d\n",
803 result, GetLastError());
805 LocalFree(typeName);
808 /* loop through the provider types to get the number of provider types
809 * after loop ends, count should be dwTypeCount + 1 so subtract 1
810 * to get actual number of provider types */
811 typeCount = 0;
812 while(pCryptEnumProviderTypesA(typeCount++, NULL, 0, &provType, NULL, &typeNameSize))
814 typeCount--;
815 ok(typeCount==dwTypeCount, "expected %d, got %d\n", dwTypeCount, typeCount);
817 /* loop past the actual number of provider types to get the error
818 * ERROR_NO_MORE_ITEMS */
819 for (typeCount = 0; typeCount < dwTypeCount + 1; typeCount++)
820 result = pCryptEnumProviderTypesA(typeCount, NULL, 0, &provType, NULL, &typeNameSize);
821 ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n",
822 GetLastError());
824 /* check expected versus actual values returned */
825 result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, NULL, &typeNameSize);
826 ok(result && typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
827 if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize)))
828 goto cleanup;
830 typeNameSize = 0xdeadbeef;
831 result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
832 ok(result, "expected TRUE, got %d\n", result);
833 ok(provType==dwProvType, "expected %d, got %d\n", dwProvType, provType);
834 if (pszTypeName)
835 ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName, typeName);
836 ok(typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
838 LocalFree(typeName);
839 cleanup:
840 LocalFree(pszTypeName);
843 static BOOL FindDfltProvRegVals(DWORD dwProvType, DWORD dwFlags, LPSTR *pszProvName, DWORD *pcbProvName)
845 HKEY hKey;
846 PSTR keyname;
847 PSTR ptr;
848 DWORD user = dwFlags & CRYPT_USER_DEFAULT;
850 LPCSTR machinestr = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
851 LPCSTR userstr = "Software\\Microsoft\\Cryptography\\Provider Type XXX";
853 keyname = LocalAlloc(LMEM_ZEROINIT, (user ? strlen(userstr) : strlen(machinestr)) + 1);
854 if (keyname)
856 user ? strcpy(keyname, userstr) : strcpy(keyname, machinestr);
857 ptr = keyname + strlen(keyname);
858 *(--ptr) = (dwProvType % 10) + '0';
859 *(--ptr) = ((dwProvType / 10) % 10) + '0';
860 *(--ptr) = (dwProvType / 100) + '0';
861 } else
862 return FALSE;
864 if (RegOpenKeyA((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey))
866 LocalFree(keyname);
867 return FALSE;
869 LocalFree(keyname);
871 if (RegQueryValueExA(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
873 if (GetLastError() != ERROR_MORE_DATA)
874 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
875 return FALSE;
878 if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))
879 return FALSE;
881 if (RegQueryValueExA(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
883 if (GetLastError() != ERROR_MORE_DATA)
884 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
885 return FALSE;
888 RegCloseKey(hKey);
890 return TRUE;
893 static void test_get_default_provider(void)
895 /* expected results */
896 DWORD dwProvType = PROV_RSA_FULL;
897 DWORD dwFlags = CRYPT_MACHINE_DEFAULT;
898 LPSTR pszProvName = NULL;
899 DWORD cbProvName;
901 /* actual results */
902 DWORD provType = PROV_RSA_FULL;
903 DWORD flags = CRYPT_MACHINE_DEFAULT;
904 LPSTR provName = NULL;
905 DWORD provNameSize;
906 DWORD result;
907 DWORD notNull = 5;
909 if(!pCryptGetDefaultProviderA)
911 win_skip("CryptGetDefaultProviderA is not available\n");
912 return;
915 if(!FindDfltProvRegVals(dwProvType, dwFlags, &pszProvName, &cbProvName))
917 skip("Could not find default provider in registry\n");
918 return;
921 /* check pdwReserved for NULL */
922 result = pCryptGetDefaultProviderA(provType, &notNull, flags, provName, &provNameSize);
923 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
924 ERROR_INVALID_PARAMETER, GetLastError());
926 /* check for invalid flag */
927 flags = 0xdeadbeef;
928 result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
929 ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %d, got %d\n",
930 NTE_BAD_FLAGS, GetLastError());
931 flags = CRYPT_MACHINE_DEFAULT;
933 /* check for invalid prov type */
934 provType = 0xdeadbeef;
935 result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
936 ok(!result && (GetLastError() == NTE_BAD_PROV_TYPE ||
937 GetLastError() == ERROR_INVALID_PARAMETER),
938 "expected NTE_BAD_PROV_TYPE or ERROR_INVALID_PARAMETER, got %d/%d\n",
939 result, GetLastError());
940 provType = PROV_RSA_FULL;
942 SetLastError(0);
944 /* alloc provName to half the size required
945 * cbProvName holds the size required */
946 provNameSize = cbProvName / 2;
947 if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
948 return;
950 result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
951 ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
952 ERROR_MORE_DATA, GetLastError());
954 LocalFree(provName);
956 /* check expected versus actual values returned */
957 result = pCryptGetDefaultProviderA(provType, NULL, flags, NULL, &provNameSize);
958 ok(result && provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
959 provNameSize = cbProvName;
961 if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
962 return;
964 provNameSize = 0xdeadbeef;
965 result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
966 ok(result, "expected TRUE, got %d\n", result);
967 if(pszProvName)
968 ok(!strcmp(pszProvName, provName), "expected %s, got %s\n", pszProvName, provName);
969 ok(provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
971 LocalFree(pszProvName);
972 LocalFree(provName);
975 static void test_set_provider_ex(void)
977 DWORD result;
978 DWORD notNull = 5;
979 LPSTR curProvName = NULL;
980 DWORD curlen;
982 /* results */
983 LPSTR pszProvName = NULL;
984 DWORD cbProvName;
986 if(!pCryptGetDefaultProviderA || !pCryptSetProviderExA)
988 win_skip("CryptGetDefaultProviderA and/or CryptSetProviderExA are not available\n");
989 return;
992 /* store the current one */
993 pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &curlen);
994 if (!(curProvName = LocalAlloc(LMEM_ZEROINIT, curlen)))
995 return;
996 result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, curProvName, &curlen);
997 ok(result, "%d\n", GetLastError());
999 /* check pdwReserved for NULL */
1000 result = pCryptSetProviderExA(MS_DEF_PROV_A, PROV_RSA_FULL, &notNull, CRYPT_MACHINE_DEFAULT);
1001 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
1002 ERROR_INVALID_PARAMETER, GetLastError());
1004 /* remove the default provider and then set it to MS_DEF_PROV/PROV_RSA_FULL */
1005 SetLastError(0xdeadbeef);
1006 result = pCryptSetProviderExA(MS_DEF_PROV_A, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT | CRYPT_DELETE_DEFAULT);
1007 if (!result)
1009 ok( GetLastError() == ERROR_ACCESS_DENIED || broken(GetLastError() == ERROR_INVALID_PARAMETER),
1010 "wrong error %u\n", GetLastError() );
1011 skip("Not enough rights to remove the default provider\n");
1012 LocalFree(curProvName);
1013 return;
1016 result = pCryptSetProviderExA(MS_DEF_PROV_A, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
1017 ok(result, "%d\n", GetLastError());
1019 /* call CryptGetDefaultProvider to see if they match */
1020 result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &cbProvName);
1021 ok(result, "%d\n", GetLastError());
1022 if (!(pszProvName = LocalAlloc(LMEM_ZEROINIT, cbProvName)))
1023 goto reset;
1025 result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, pszProvName, &cbProvName);
1026 ok(result && !strcmp(MS_DEF_PROV_A, pszProvName), "expected %s, got %s\n", MS_DEF_PROV_A, pszProvName);
1027 ok(result && cbProvName==(strlen(MS_DEF_PROV_A) + 1), "expected %i, got %d\n", (lstrlenA(MS_DEF_PROV_A) + 1), cbProvName);
1029 LocalFree(pszProvName);
1031 reset:
1032 /* Set the provider back to its original */
1033 result = pCryptSetProviderExA(curProvName, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
1034 ok(result, "%d\n", GetLastError());
1035 LocalFree(curProvName);
1038 static void test_machine_guid(void)
1040 char originalGuid[40];
1041 LONG r;
1042 HKEY key;
1043 DWORD size;
1044 HCRYPTPROV hCryptProv;
1045 BOOL restoreGuid = FALSE, ret;
1047 r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography",
1048 0, KEY_ALL_ACCESS, &key);
1049 if (r != ERROR_SUCCESS)
1051 skip("couldn't open HKLM\\Software\\Microsoft\\Cryptography\n");
1052 return;
1054 /* Cache existing MachineGuid, and delete it */
1055 size = sizeof(originalGuid);
1056 r = RegQueryValueExA(key, "MachineGuid", NULL, NULL, (BYTE *)originalGuid,
1057 &size);
1058 if (r == ERROR_SUCCESS)
1060 restoreGuid = TRUE;
1061 r = RegDeleteValueA(key, "MachineGuid");
1062 ok(!r || broken(r == ERROR_ACCESS_DENIED) /*win8*/, "RegDeleteValueA failed: %d\n", r);
1063 if (r == ERROR_ACCESS_DENIED)
1065 skip("broken virtualization on HKLM\\Software\\Microsoft\\Cryptography\n");
1066 RegCloseKey(key);
1067 return;
1070 else
1071 ok(r == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n",
1073 /* Create and release a provider */
1074 ret = CryptAcquireContextA(&hCryptProv, szKeySet, NULL, PROV_RSA_FULL, 0);
1075 ok(ret || broken(!ret && GetLastError() == NTE_KEYSET_ENTRY_BAD /* NT4 */),
1076 "CryptAcquireContextA failed: %08x\n", GetLastError());
1077 ret = CryptReleaseContext(hCryptProv, 0);
1078 ok(ret, "got %u\n", GetLastError());
1080 if (restoreGuid)
1081 RegSetValueExA(key, "MachineGuid", 0, REG_SZ, (const BYTE *)originalGuid,
1082 strlen(originalGuid)+1);
1083 RegCloseKey(key);
1086 #define key_length 16
1088 static const unsigned char key[key_length] =
1089 { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd,
1090 0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 };
1092 static void test_rc2_keylen(void)
1094 struct KeyBlob
1096 BLOBHEADER header;
1097 DWORD key_size;
1098 BYTE key_data[2048];
1099 } key_blob;
1101 HCRYPTPROV provider;
1102 HCRYPTKEY hkey = 0;
1103 BOOL ret;
1105 SetLastError(0xdeadbeef);
1106 ret = CryptAcquireContextA(&provider, NULL, NULL,
1107 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1108 ok(ret, "CryptAcquireContext error %u\n", GetLastError());
1109 if (ret)
1111 key_blob.header.bType = PLAINTEXTKEYBLOB;
1112 key_blob.header.bVersion = CUR_BLOB_VERSION;
1113 key_blob.header.reserved = 0;
1114 key_blob.header.aiKeyAlg = CALG_RC2;
1115 key_blob.key_size = sizeof(key);
1116 memcpy(key_blob.key_data, key, key_length);
1118 /* Importing a 16-byte key works with the default provider. */
1119 SetLastError(0xdeadbeef);
1120 ret = CryptImportKey(provider, (BYTE *)&key_blob, sizeof(BLOBHEADER) + sizeof(DWORD) + key_blob.key_size,
1121 0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1122 /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
1123 ok(ret ||
1124 broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1125 "CryptImportKey error %08x\n", GetLastError());
1126 if (ret)
1127 CryptDestroyKey(hkey);
1129 ret = CryptReleaseContext(provider, 0);
1130 ok(ret, "got %u\n", GetLastError());
1133 SetLastError(0xdeadbeef);
1134 ret = CryptAcquireContextA(&provider, NULL, MS_DEF_PROV_A,
1135 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1136 ok(ret, "CryptAcquireContext error %08x\n", GetLastError());
1138 if (ret)
1140 /* Importing a 16-byte key doesn't work with the base provider.. */
1141 SetLastError(0xdeadbeef);
1142 ret = CryptImportKey(provider, (BYTE *)&key_blob, sizeof(BLOBHEADER) + sizeof(DWORD) + key_blob.key_size,
1143 0, 0, &hkey);
1144 ok(!ret && (GetLastError() == NTE_BAD_DATA ||
1145 GetLastError() == NTE_BAD_LEN || /* Win7 */
1146 GetLastError() == NTE_BAD_TYPE || /* W2K */
1147 GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */
1148 "unexpected error %08x\n", GetLastError());
1149 /* but importing an 56-bit (7-byte) key does.. */
1150 key_blob.key_size = 7;
1151 SetLastError(0xdeadbeef);
1152 ret = CryptImportKey(provider, (BYTE *)&key_blob, sizeof(BLOBHEADER) + sizeof(DWORD) + key_blob.key_size,
1153 0, 0, &hkey);
1154 ok(ret ||
1155 broken(!ret && GetLastError() == NTE_BAD_TYPE) || /* W2K */
1156 broken(!ret && GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */
1157 "CryptAcquireContext error %08x\n", GetLastError());
1158 if (ret)
1159 CryptDestroyKey(hkey);
1160 /* as does importing a 16-byte key with the base provider when
1161 * CRYPT_IPSEC_HMAC_KEY is specified.
1163 key_blob.key_size = sizeof(key);
1164 SetLastError(0xdeadbeef);
1165 ret = CryptImportKey(provider, (BYTE *)&key_blob, sizeof(BLOBHEADER) + sizeof(DWORD) + key_blob.key_size,
1166 0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1167 /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
1168 ok(ret ||
1169 broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1170 "CryptImportKey error %08x\n", GetLastError());
1171 if (ret)
1172 CryptDestroyKey(hkey);
1174 ret = CryptReleaseContext(provider, 0);
1175 ok(ret, "got %u\n", GetLastError());
1178 key_blob.key_size = sizeof(key);
1179 SetLastError(0xdeadbeef);
1180 ret = CryptAcquireContextA(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1181 ok(ret, "CryptAcquireContext error %08x\n", GetLastError());
1183 if (ret)
1185 /* Importing a 16-byte key also works with the default provider when
1186 * CRYPT_IPSEC_HMAC_KEY is specified.
1188 SetLastError(0xdeadbeef);
1189 ret = CryptImportKey(provider, (BYTE *)&key_blob, sizeof(BLOBHEADER) + sizeof(DWORD) + key_blob.key_size,
1190 0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1191 ok(ret ||
1192 broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1193 "CryptImportKey error %08x\n", GetLastError());
1194 if (ret)
1195 CryptDestroyKey(hkey);
1197 /* There is no apparent limit to the size of the input key when
1198 * CRYPT_IPSEC_HMAC_KEY is specified.
1200 key_blob.key_size = sizeof(key_blob.key_data);
1201 SetLastError(0xdeadbeef);
1202 ret = CryptImportKey(provider, (BYTE *)&key_blob, sizeof(BLOBHEADER) + sizeof(DWORD) + key_blob.key_size,
1203 0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1204 ok(ret ||
1205 broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1206 "CryptImportKey error %08x\n", GetLastError());
1207 if (ret)
1208 CryptDestroyKey(hkey);
1210 ret = CryptReleaseContext(provider, 0);
1211 ok(ret, "got %u\n", GetLastError());
1215 static void test_SystemFunction036(void)
1217 BOOL ret;
1218 int test;
1220 if (!pSystemFunction036)
1222 win_skip("SystemFunction036 is not available\n");
1223 return;
1226 ret = pSystemFunction036(NULL, 0);
1227 ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
1229 /* Test crashes on Windows. */
1230 if (0)
1232 SetLastError(0xdeadbeef);
1233 ret = pSystemFunction036(NULL, 5);
1234 trace("ret = %d, GetLastError() = %d\n", ret, GetLastError());
1237 ret = pSystemFunction036(&test, 0);
1238 ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
1240 ret = pSystemFunction036(&test, sizeof(int));
1241 ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
1244 static void test_container_sd(void)
1246 HCRYPTPROV prov;
1247 SECURITY_DESCRIPTOR *sd;
1248 DWORD len, err;
1249 BOOL ret;
1251 ret = CryptAcquireContextA(&prov, "winetest", "Microsoft Enhanced Cryptographic Provider v1.0",
1252 PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_NEWKEYSET);
1253 ok(ret, "got %u\n", GetLastError());
1255 len = 0;
1256 SetLastError(0xdeadbeef);
1257 ret = CryptGetProvParam(prov, PP_KEYSET_SEC_DESCR, NULL, &len, OWNER_SECURITY_INFORMATION);
1258 err = GetLastError();
1259 ok(ret, "got %u\n", err);
1260 ok(err == ERROR_INSUFFICIENT_BUFFER || broken(err == ERROR_INVALID_PARAMETER), "got %u\n", err);
1261 ok(len, "expected len > 0\n");
1263 sd = HeapAlloc(GetProcessHeap(), 0, len);
1264 ret = CryptGetProvParam(prov, PP_KEYSET_SEC_DESCR, (BYTE *)sd, &len, OWNER_SECURITY_INFORMATION);
1265 ok(ret, "got %u\n", GetLastError());
1266 HeapFree(GetProcessHeap(), 0, sd);
1268 ret = CryptReleaseContext(prov, 0);
1269 ok(ret, "got %u\n", GetLastError());
1271 prov = 0xdeadbeef;
1272 ret = CryptAcquireContextA(&prov, "winetest", "Microsoft Enhanced Cryptographic Provider v1.0",
1273 PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_DELETEKEYSET);
1274 ok(ret, "got %u\n", GetLastError());
1275 ok(prov == 0, "got %ld\n", prov);
1278 START_TEST(crypt)
1280 init_function_pointers();
1282 test_rc2_keylen();
1284 init_environment();
1285 test_CryptReleaseContext();
1286 test_acquire_context();
1287 test_incorrect_api_usage();
1288 test_verify_sig();
1289 test_machine_guid();
1290 test_container_sd();
1291 clean_up_environment();
1293 test_enum_providers();
1294 test_enum_provider_types();
1295 test_get_default_provider();
1296 test_set_provider_ex();
1297 test_SystemFunction036();