2 * Unit tests for rsaenh functions
4 * Copyright (c) 2004 Michael Jung
5 * Copyright (c) 2006 Juan Lang
6 * Copyright (c) 2007 Vijay Kiran Kamuju
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
32 static HCRYPTPROV hProv;
33 static const char szContainer[] = "winetest";
34 static const char szProvider[] = MS_ENHANCED_PROV_A;
36 typedef struct _ctdatatype {
37 unsigned char origstr[32];
38 unsigned char decstr[32];
44 static const cryptdata cTestData[4] = {
46 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
49 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
52 {'a','b','c','d','e','f','g','h',0},
55 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
60 * 1. Take the MD5 Hash of the container name (with an extra null byte)
61 * 2. Turn the hash into a 4 DWORD hex value
63 * 4. Add the MachineGuid
66 static void uniquecontainer(char *unique)
68 /* MD5 hash of "winetest\0" in 4 DWORD hex */
69 static const char szContainer_md5[] = "9d20fd8d05ed2b8455d125d0bf6d6a70";
70 static const char szCryptography[] = "Software\\Microsoft\\Cryptography";
71 static const char szMachineGuid[] = "MachineGuid";
74 DWORD size = MAX_PATH;
77 /* Get the MachineGUID */
78 ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szCryptography, 0, KEY_READ | KEY_WOW64_64KEY, &hkey);
79 if (ret == ERROR_ACCESS_DENIED)
81 /* Windows 2000 can't handle KEY_WOW64_64KEY */
82 RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
84 RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
87 lstrcpy(unique, szContainer_md5);
89 lstrcat(unique, guid);
92 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
95 printf("%s: ",heading);
97 printf("0x%02x,",pb[i]);
101 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
104 static void trace_hex(BYTE *pbData, DWORD dwLen) {
108 for (i = 0; i < dwLen-7; i+=8) {
109 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
110 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
111 pbData[i+6], pbData[i+7]);
114 for (j=0; i<dwLen; j++,i++) {
115 sprintf(szTemp+6*j, "0x%02x,\n", pbData[i]);
121 static int init_base_environment(DWORD dwKeyFlags)
126 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
128 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
130 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
131 ok(!result && (GetLastError()==NTE_BAD_FLAGS ||
132 broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */)),
133 "%d, %08x\n", result, GetLastError());
135 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
137 ok(GetLastError()==NTE_BAD_KEYSET ||
138 broken(GetLastError() == NTE_TEMPORARY_PROFILE /* some Win7 setups */) ||
139 broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */),
140 "%08x\n", GetLastError());
141 if (GetLastError()!=NTE_BAD_KEYSET)
143 win_skip("RSA full provider not available\n");
146 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
148 ok(result, "%08x\n", GetLastError());
151 win_skip("Couldn't create crypto provider\n");
154 result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey);
155 ok(result, "%08x\n", GetLastError());
156 if (result) CryptDestroyKey(hKey);
157 result = CryptGenKey(hProv, AT_SIGNATURE, dwKeyFlags, &hKey);
158 ok(result, "%08x\n", GetLastError());
159 if (result) CryptDestroyKey(hKey);
164 static void clean_up_base_environment(void)
168 SetLastError(0xdeadbeef);
169 result = CryptReleaseContext(hProv, 1);
170 ok(!result || broken(result) /* Win98 */, "Expected failure\n");
171 ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
173 /* Just to prove that Win98 also released the CSP */
174 SetLastError(0xdeadbeef);
175 result = CryptReleaseContext(hProv, 0);
176 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
178 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
181 static int init_aes_environment(void)
186 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
188 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
190 /* we are using NULL as provider name for RSA_AES provider as the provider
191 * names are different in Windows XP and Vista. Its different as to what
192 * its defined in the SDK on Windows XP.
193 * This provider is available on Windows XP, Windows 2003 and Vista. */
195 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
196 if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
198 win_skip("RSA_AES provider not supported\n");
201 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
203 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
205 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
206 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
207 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
209 ok(result, "%08x\n", GetLastError());
210 if (!result) return 0;
211 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
212 ok(result, "%08x\n", GetLastError());
213 if (result) CryptDestroyKey(hKey);
214 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
215 ok(result, "%08x\n", GetLastError());
216 if (result) CryptDestroyKey(hKey);
221 static void clean_up_aes_environment(void)
225 result = CryptReleaseContext(hProv, 1);
226 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
228 CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
231 static void test_prov(void)
236 dwLen = (DWORD)sizeof(DWORD);
237 SetLastError(0xdeadbeef);
238 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
239 if (!result && GetLastError() == NTE_BAD_TYPE)
240 skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
242 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
244 dwLen = (DWORD)sizeof(DWORD);
245 SetLastError(0xdeadbeef);
246 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
247 if (!result && GetLastError() == NTE_BAD_TYPE)
248 skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
250 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
253 static void test_gen_random(void)
256 BYTE rnd1[16], rnd2[16];
258 memset(rnd1, 0, sizeof(rnd1));
259 memset(rnd2, 0, sizeof(rnd2));
261 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
262 if (!result && GetLastError() == NTE_FAIL) {
263 /* rsaenh compiled without OpenSSL */
267 ok(result, "%08x\n", GetLastError());
269 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
270 ok(result, "%08x\n", GetLastError());
272 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
275 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
279 unsigned char pbData[2000];
283 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
284 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
286 /* rsaenh compiled without OpenSSL */
287 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
290 ok(result, "%08x\n", GetLastError());
291 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
292 ok(result, "%08x\n", GetLastError());
293 if (!result) return FALSE;
294 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
295 ok(result, "%08x\n", GetLastError());
296 if (!result) return FALSE;
298 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
299 ok(result, "%08x\n", GetLastError());
300 CryptDestroyHash(hHash);
304 static void test_hashes(void)
306 static const unsigned char md2hash[16] = {
307 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
308 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
309 static const unsigned char md4hash[16] = {
310 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
311 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
312 static const unsigned char empty_md5hash[16] = {
313 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
314 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
315 static const unsigned char md5hash[16] = {
316 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
317 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
318 static const unsigned char sha1hash[20] = {
319 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
320 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
321 unsigned char pbData[2048];
323 HCRYPTHASH hHash, hHashClone;
325 BYTE pbHashValue[36];
326 DWORD hashlen, len, error;
329 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
332 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
334 /* rsaenh compiled without OpenSSL */
335 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
337 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
338 ok(result, "%08x\n", GetLastError());
341 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
342 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
345 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
346 ok(result, "%08x\n", GetLastError());
348 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
350 result = CryptDestroyHash(hHash);
351 ok(result, "%08x\n", GetLastError());
355 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
356 ok(result, "%08x\n", GetLastError());
358 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
359 ok(result, "%08x\n", GetLastError());
362 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
363 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
366 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
367 ok(result, "%08x\n", GetLastError());
369 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
371 result = CryptDestroyHash(hHash);
372 ok(result, "%08x\n", GetLastError());
375 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
376 ok(result, "%08x\n", GetLastError());
379 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
380 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
382 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
383 ok(result, "%08x\n", GetLastError());
386 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
387 ok(result, "%08x\n", GetLastError());
389 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
391 result = CryptDestroyHash(hHash);
392 ok(result, "%08x\n", GetLastError());
394 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
395 ok(result, "%08x\n", GetLastError());
397 /* The hash is available even if CryptHashData hasn't been called */
399 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
400 ok(result, "%08x\n", GetLastError());
402 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
404 /* It's also stable: getting it twice results in the same value */
405 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
406 ok(result, "%08x\n", GetLastError());
408 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
410 /* Can't add data after the hash been retrieved */
411 SetLastError(0xdeadbeef);
412 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
413 ok(!result, "Expected failure\n");
414 ok(GetLastError() == NTE_BAD_HASH_STATE ||
415 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
416 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
418 /* You can still retrieve the hash, its value just hasn't changed */
419 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
420 ok(result, "%08x\n", GetLastError());
422 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
424 result = CryptDestroyHash(hHash);
425 ok(result, "%08x\n", GetLastError());
428 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
429 ok(result, "%08x\n", GetLastError());
431 result = CryptHashData(hHash, pbData, 5, 0);
432 ok(result, "%08x\n", GetLastError());
434 if(pCryptDuplicateHash) {
435 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
436 ok(result, "%08x\n", GetLastError());
438 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
439 ok(result, "%08x\n", GetLastError());
442 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
443 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
446 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
447 ok(result, "%08x\n", GetLastError());
449 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
451 result = CryptDestroyHash(hHashClone);
452 ok(result, "%08x\n", GetLastError());
455 result = CryptDestroyHash(hHash);
456 ok(result, "%08x\n", GetLastError());
458 /* The SHA-2 variants aren't supported in the RSA full provider */
459 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
460 ok(!result && GetLastError() == NTE_BAD_ALGID,
461 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
462 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
463 ok(!result && GetLastError() == NTE_BAD_ALGID,
464 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
465 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
466 ok(!result && GetLastError() == NTE_BAD_ALGID,
467 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
469 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
470 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
472 result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash);
473 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
475 /* release provider before using the hash */
476 result = CryptReleaseContext(prov, 0);
477 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
479 SetLastError(0xdeadbeef);
480 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
481 error = GetLastError();
482 ok(!result, "CryptHashData succeeded\n");
483 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
485 SetLastError(0xdeadbeef);
486 result = CryptDestroyHash(hHash);
487 error = GetLastError();
488 ok(!result, "CryptDestroyHash succeeded\n");
489 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
491 if (!pCryptDuplicateHash)
493 win_skip("CryptDuplicateHash is not available\n");
497 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
498 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
500 result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
501 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
503 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
504 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
506 result = pCryptDuplicateHash(hHash, NULL, 0, &hHashClone);
507 ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
510 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
511 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
513 /* add data after duplicating the hash */
514 result = CryptHashData(hHash, (const BYTE *)"more data", sizeof("more data"), 0);
515 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
517 result = CryptDestroyHash(hHash);
518 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
520 result = CryptDestroyHash(hHashClone);
521 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
523 result = CryptReleaseContext(prov, 0);
524 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
527 static void test_block_cipher_modes(void)
529 static const BYTE plain[23] = {
530 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
531 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
532 static const BYTE ecb[24] = {
533 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
534 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
535 static const BYTE cbc[24] = {
536 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
537 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
538 static const BYTE cfb[24] = {
539 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
540 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
546 result = derive_key(CALG_RC2, &hKey, 40);
549 memcpy(abData, plain, sizeof(plain));
551 dwMode = CRYPT_MODE_ECB;
552 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
553 ok(result, "%08x\n", GetLastError());
555 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
556 ok(result, "%08x\n", GetLastError());
557 ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
560 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
561 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
562 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
564 SetLastError(ERROR_SUCCESS);
566 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
567 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
568 "%08x, dwLen: %d\n", GetLastError(), dwLen);
570 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
571 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
572 "%08x, dwLen: %d\n", GetLastError(), dwLen);
574 dwMode = CRYPT_MODE_CBC;
575 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
576 ok(result, "%08x\n", GetLastError());
579 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
580 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
581 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
584 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
585 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
586 "%08x, dwLen: %d\n", GetLastError(), dwLen);
588 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
589 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
590 "%08x, dwLen: %d\n", GetLastError(), dwLen);
592 dwMode = CRYPT_MODE_CFB;
593 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
594 ok(result, "%08x\n", GetLastError());
597 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
598 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
601 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
602 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
603 "%08x, dwLen: %d\n", GetLastError(), dwLen);
606 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
607 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
610 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
611 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
612 "%08x, dwLen: %d\n", GetLastError(), dwLen);
614 dwMode = CRYPT_MODE_OFB;
615 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
616 ok(result, "%08x\n", GetLastError());
619 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
620 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
622 CryptDestroyKey(hKey);
625 static void test_3des112(void)
630 unsigned char pbData[16];
633 result = derive_key(CALG_3DES_112, &hKey, 0);
635 /* rsaenh compiled without OpenSSL */
636 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
640 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
643 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
644 ok(result, "%08x\n", GetLastError());
646 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
647 ok(result, "%08x\n", GetLastError());
651 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
653 dwLen = cTestData[i].enclen;
654 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
655 ok(result, "%08x\n", GetLastError());
656 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
658 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
659 ok(result, "%08x\n", GetLastError());
660 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
661 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
662 if((dwLen != cTestData[i].enclen) ||
663 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
665 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
666 printBytes("got",pbData,dwLen);
669 result = CryptDestroyKey(hKey);
670 ok(result, "%08x\n", GetLastError());
673 static void test_des(void)
678 unsigned char pbData[16];
681 result = derive_key(CALG_DES, &hKey, 56);
683 /* rsaenh compiled without OpenSSL */
684 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
688 dwMode = CRYPT_MODE_ECB;
689 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
690 ok(result, "%08x\n", GetLastError());
692 dwLen = sizeof(DWORD);
693 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
694 ok(result, "%08x\n", GetLastError());
696 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
699 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
700 ok(result, "%08x\n", GetLastError());
702 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
703 ok(result, "%08x\n", GetLastError());
707 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
709 dwLen = cTestData[i].enclen;
710 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
711 ok(result, "%08x\n", GetLastError());
712 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
714 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
715 ok(result, "%08x\n", GetLastError());
716 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
717 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
718 if((dwLen != cTestData[i].enclen) ||
719 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
721 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
722 printBytes("got",pbData,dwLen);
726 result = CryptDestroyKey(hKey);
727 ok(result, "%08x\n", GetLastError());
730 static void test_3des(void)
735 unsigned char pbData[16];
736 static const BYTE des3[16] = {
737 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
738 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
741 result = derive_key(CALG_3DES, &hKey, 0);
744 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
747 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
748 ok(result, "%08x\n", GetLastError());
750 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
752 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
753 ok(result, "%08x\n", GetLastError());
757 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
759 dwLen = cTestData[i].enclen;
760 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
761 ok(result, "%08x\n", GetLastError());
762 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
764 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
765 ok(result, "%08x\n", GetLastError());
766 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
767 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
768 if((dwLen != cTestData[i].enclen) ||
769 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
771 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
772 printBytes("got",pbData,dwLen);
775 result = CryptDestroyKey(hKey);
776 ok(result, "%08x\n", GetLastError());
779 static void test_aes(int keylen)
784 unsigned char pbData[16];
790 result = derive_key(CALG_AES_256, &hKey, 0);
793 result = derive_key(CALG_AES_192, &hKey, 0);
797 result = derive_key(CALG_AES_128, &hKey, 0);
802 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
804 /* AES provider doesn't support salt */
805 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
806 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == ERROR_NO_TOKEN /* Win7 */),
807 "expected NTE_BAD_KEY or ERROR_NO_TOKEN, got %08x\n", GetLastError());
810 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
811 ok(result, "%08x\n", GetLastError());
813 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
814 ok(result, "%08x\n", GetLastError());
818 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
820 dwLen = cTestData[i].enclen;
821 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
822 ok(result, "%08x\n", GetLastError());
823 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
825 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
826 ok(result, "%08x\n", GetLastError());
827 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
828 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
829 if((dwLen != cTestData[i].enclen) ||
830 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
832 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
833 printBytes("got",pbData,dwLen);
836 result = CryptDestroyKey(hKey);
837 ok(result, "%08x\n", GetLastError());
840 static void test_sha2(void)
842 static const unsigned char sha256hash[32] = {
843 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
844 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
845 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
848 static const unsigned char sha384hash[48] = {
849 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
850 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
851 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
852 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
853 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
855 static const unsigned char sha512hash[64] = {
856 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
857 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
858 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
859 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
860 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
861 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
862 0xb7, 0xf4, 0x81, 0xd4
864 unsigned char pbData[2048];
867 BYTE pbHashValue[64];
871 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
874 SetLastError(0xdeadbeef);
875 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
876 if (!result && GetLastError() == NTE_BAD_ALGID) {
877 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
880 ok(result, "%08x\n", GetLastError());
883 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
884 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
886 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
887 ok(result, "%08x\n", GetLastError());
890 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
891 ok(result, "%08x\n", GetLastError());
893 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
895 result = CryptDestroyHash(hHash);
896 ok(result, "%08x\n", GetLastError());
900 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
901 ok(result, "%08x\n", GetLastError());
904 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
905 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
907 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
908 ok(result, "%08x\n", GetLastError());
911 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
912 ok(result, "%08x\n", GetLastError());
914 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
916 result = CryptDestroyHash(hHash);
917 ok(result, "%08x\n", GetLastError());
921 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
922 ok(result, "%08x\n", GetLastError());
925 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
926 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
928 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
929 ok(result, "%08x\n", GetLastError());
932 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
933 ok(result, "%08x\n", GetLastError());
935 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
937 result = CryptDestroyHash(hHash);
938 ok(result, "%08x\n", GetLastError());
942 static void test_rc2(void)
944 static const BYTE rc2_40_encrypted[16] = {
945 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
946 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
947 static const BYTE rc2_128_encrypted[] = {
948 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
953 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
955 unsigned char pbData[2000], pbHashValue[16];
958 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
961 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
963 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
965 CRYPT_INTEGER_BLOB salt;
967 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
968 ok(result, "%08x\n", GetLastError());
971 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
972 ok(result, "%08x\n", GetLastError());
974 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
975 ok(result, "%08x\n", GetLastError());
977 dwLen = sizeof(DWORD);
978 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
979 ok(result, "%08x\n", GetLastError());
981 dwMode = CRYPT_MODE_CBC;
982 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
983 ok(result, "%08x\n", GetLastError());
985 dwLen = sizeof(DWORD);
986 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
987 ok(result, "%08x\n", GetLastError());
989 dwModeBits = 0xdeadbeef;
990 dwLen = sizeof(DWORD);
991 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
992 ok(result, "%08x\n", GetLastError());
994 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
995 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
996 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
997 " got %08x\n", dwModeBits);
999 dwLen = sizeof(DWORD);
1000 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1001 ok(result, "%08x\n", GetLastError());
1003 dwLen = sizeof(DWORD);
1004 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1005 ok(result, "%08x\n", GetLastError());
1007 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1008 ok(result, "%08x\n", GetLastError());
1009 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1010 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1011 HeapFree(GetProcessHeap(), 0, pbTemp);
1013 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1014 ok(result, "%08x\n", GetLastError());
1015 /* The default salt length is always 11... */
1016 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1017 /* and the default salt is always empty. */
1018 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1019 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1020 for (i=0; i<dwLen; i++)
1021 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1022 HeapFree(GetProcessHeap(), 0, pbTemp);
1024 dwLen = sizeof(DWORD);
1025 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1027 result = CryptDestroyHash(hHash);
1028 ok(result, "%08x\n", GetLastError());
1031 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1032 ok(result, "%08x\n", GetLastError());
1034 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1036 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1037 ok(result, "%08x\n", GetLastError());
1038 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1039 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1040 HeapFree(GetProcessHeap(), 0, pbTemp);
1042 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1043 ok(result, "%08x\n", GetLastError());
1045 /* Setting the salt also succeeds... */
1046 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1047 ok(result, "setting salt failed: %08x\n", GetLastError());
1048 /* but the resulting salt length is now zero? */
1050 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1051 ok(result, "%08x\n", GetLastError());
1053 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1054 "unexpected salt length %d\n", dwLen);
1055 /* What sizes salt can I set? */
1056 salt.pbData = pbData;
1057 for (i=0; i<24; i++)
1060 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1061 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1062 /* The returned salt length is the same as the set salt length */
1063 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1064 ok(result, "%08x\n", GetLastError());
1065 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1068 SetLastError(0xdeadbeef);
1069 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1071 broken(result), /* Win9x, WinMe, NT4, W2K */
1072 "%08x\n", GetLastError());
1074 result = CryptDestroyKey(hKey);
1075 ok(result, "%08x\n", GetLastError());
1078 /* Again, but test setting the effective key len */
1079 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1081 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1083 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1085 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1086 ok(result, "%08x\n", GetLastError());
1089 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1090 ok(result, "%08x\n", GetLastError());
1092 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1093 ok(result, "%08x\n", GetLastError());
1095 SetLastError(0xdeadbeef);
1096 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1097 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1099 SetLastError(0xdeadbeef);
1100 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1101 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1103 SetLastError(0xdeadbeef);
1104 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1106 dwLen = sizeof(dwKeyLen);
1107 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1108 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1109 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1110 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1113 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1114 ok(result, "%d\n", GetLastError());
1116 dwLen = sizeof(dwKeyLen);
1117 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1118 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1119 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1120 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1122 result = CryptDestroyHash(hHash);
1123 ok(result, "%08x\n", GetLastError());
1126 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1127 ok(result, "%08x\n", GetLastError());
1129 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1130 "RC2 encryption failed!\n");
1132 /* Oddly enough this succeeds, though it should have no effect */
1134 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1135 ok(result, "%d\n", GetLastError());
1137 result = CryptDestroyKey(hKey);
1138 ok(result, "%08x\n", GetLastError());
1142 static void test_rc4(void)
1144 static const BYTE rc4[16] = {
1145 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1146 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1150 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1151 unsigned char pbData[2000], *pbTemp;
1152 unsigned char pszBuffer[256];
1155 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1158 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1160 /* rsaenh compiled without OpenSSL */
1161 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1163 CRYPT_INTEGER_BLOB salt;
1165 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1166 ok(result, "%08x\n", GetLastError());
1169 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1170 ok(result, "%08x\n", GetLastError());
1172 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1173 ok(result, "%08x\n", GetLastError());
1175 dwLen = sizeof(DWORD);
1176 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1177 ok(result, "%08x\n", GetLastError());
1179 dwLen = sizeof(DWORD);
1180 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1181 ok(result, "%08x\n", GetLastError());
1183 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1184 ok(result, "%08x\n", GetLastError());
1185 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1186 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1187 HeapFree(GetProcessHeap(), 0, pbTemp);
1189 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1190 ok(result, "%08x\n", GetLastError());
1191 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1192 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1193 HeapFree(GetProcessHeap(), 0, pbTemp);
1195 dwLen = sizeof(DWORD);
1196 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1198 result = CryptDestroyHash(hHash);
1199 ok(result, "%08x\n", GetLastError());
1202 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1203 ok(result, "%08x\n", GetLastError());
1205 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1206 ok(result, "%08x\n", GetLastError());
1208 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1210 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1211 ok(result, "%08x\n", GetLastError());
1213 /* Setting the salt also succeeds... */
1214 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1215 ok(result, "setting salt failed: %08x\n", GetLastError());
1216 /* but the resulting salt length is now zero? */
1218 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1219 ok(result, "%08x\n", GetLastError());
1221 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1222 "unexpected salt length %d\n", dwLen);
1223 /* What sizes salt can I set? */
1224 salt.pbData = pbData;
1225 for (i=0; i<24; i++)
1228 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1229 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1230 /* The returned salt length is the same as the set salt length */
1231 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1232 ok(result, "%08x\n", GetLastError());
1233 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1236 SetLastError(0xdeadbeef);
1237 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1239 broken(result), /* Win9x, WinMe, NT4, W2K */
1240 "%08x\n", GetLastError());
1242 result = CryptDestroyKey(hKey);
1243 ok(result, "%08x\n", GetLastError());
1247 static void test_hmac(void) {
1251 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1252 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1255 static const BYTE hmac[16] = {
1256 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1257 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1260 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1262 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1264 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1265 ok(result, "%08x\n", GetLastError());
1266 if (!result) return;
1268 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1269 ok(result, "%08x\n", GetLastError());
1271 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1272 ok(result, "%08x\n", GetLastError());
1274 dwLen = sizeof(abData)/sizeof(BYTE);
1275 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1276 ok(result, "%08x\n", GetLastError());
1278 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1280 result = CryptDestroyHash(hHash);
1281 ok(result, "%08x\n", GetLastError());
1283 result = CryptDestroyKey(hKey);
1284 ok(result, "%08x\n", GetLastError());
1286 /* Provoke errors */
1287 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1288 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1291 static void test_mac(void) {
1296 BYTE abData[256], abEnc[264];
1297 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1300 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1301 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1303 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1306 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1307 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1309 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1310 ok(result, "%08x\n", GetLastError());
1311 if (!result) return;
1313 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1314 ok(result, "%08x\n", GetLastError());
1316 dwLen = sizeof(abData)/sizeof(BYTE);
1317 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1318 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1320 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1322 result = CryptDestroyHash(hHash);
1323 ok(result, "%08x\n", GetLastError());
1325 result = CryptDestroyKey(hKey);
1326 ok(result, "%08x\n", GetLastError());
1328 /* Provoke errors */
1329 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1331 SetLastError(0xdeadbeef);
1332 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1333 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1334 broken(result), /* Win9x, WinMe, NT4, W2K */
1335 "%08x\n", GetLastError());
1337 result = CryptDestroyKey(hKey);
1338 ok(result, "%08x\n", GetLastError());
1341 static BYTE abPlainPrivateKey[596] = {
1342 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1343 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1344 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1345 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1346 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1347 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1348 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1349 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1350 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1351 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1352 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1353 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1354 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1355 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1356 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1357 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1358 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1359 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1360 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1361 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1362 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1363 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1364 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1365 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1366 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1367 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1368 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1369 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1370 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1371 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1372 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1373 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1374 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1375 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1376 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1377 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1378 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1379 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1380 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1381 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1382 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1383 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1384 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1385 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1386 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1387 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1388 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1389 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1390 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1391 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1392 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1393 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1394 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1395 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1396 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1397 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1398 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1399 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1400 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1401 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1402 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1403 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1404 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1405 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1406 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1407 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1408 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1409 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1410 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1411 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1412 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1413 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1414 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1415 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1416 0xf2, 0x5d, 0x58, 0x07
1419 static void test_import_private(void)
1422 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1424 static BYTE abSessionKey[148] = {
1425 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1426 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1427 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1428 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1429 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1430 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1431 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1432 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1433 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1434 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1435 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1436 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1437 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1438 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1439 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1440 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1441 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1442 0x04, 0x8c, 0x49, 0x92
1444 static BYTE abEncryptedMessage[12] = {
1445 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1446 0x1c, 0xfd, 0xde, 0x71
1449 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1450 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1452 /* rsaenh compiled without OpenSSL */
1453 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1457 dwLen = (DWORD)sizeof(abSessionKey);
1458 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1459 ok(result, "%08x\n", GetLastError());
1460 if (!result) return;
1463 dwLen = sizeof(DWORD);
1464 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1465 ok(result, "%08x\n", GetLastError());
1467 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1468 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1469 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1470 " got %08x\n", dwVal);
1472 dwLen = (DWORD)sizeof(abEncryptedMessage);
1473 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1474 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1475 "%08x, len: %d\n", GetLastError(), dwLen);
1476 CryptDestroyKey(hSessionKey);
1478 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1480 dwLen = (DWORD)sizeof(abSessionKey);
1481 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1482 ok(result, "%08x\n", GetLastError());
1483 CryptDestroyKey(hSessionKey);
1484 if (!result) return;
1486 dwLen = (DWORD)sizeof(abSessionKey);
1487 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1488 ok(result, "%08x\n", GetLastError());
1489 if (!result) return;
1491 CryptDestroyKey(hSessionKey);
1492 CryptDestroyKey(hKeyExchangeKey);
1495 static void test_verify_signature(void) {
1497 HCRYPTKEY hPubSignKey;
1498 BYTE abData[] = "Wine rocks!";
1500 BYTE abPubKey[148] = {
1501 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1502 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1503 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1504 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1505 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1506 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1507 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1508 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1509 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1510 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1511 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1512 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1513 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1514 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1515 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1516 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1517 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1518 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1519 0xe1, 0x21, 0x50, 0xac
1521 /* md2 with hash oid */
1522 BYTE abSignatureMD2[128] = {
1523 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1524 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1525 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1526 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1527 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1528 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1529 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1530 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1531 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1532 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1533 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1534 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1535 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1536 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1537 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1538 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1540 /* md2 without hash oid */
1541 BYTE abSignatureMD2NoOID[128] = {
1542 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1543 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1544 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1545 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1546 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1547 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1548 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1549 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1550 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1551 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1552 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1553 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1554 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1555 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1556 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1557 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1559 /* md4 with hash oid */
1560 BYTE abSignatureMD4[128] = {
1561 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1562 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1563 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1564 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1565 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1566 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1567 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1568 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1569 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1570 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1571 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1572 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1573 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1574 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1575 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1576 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1578 /* md4 without hash oid */
1579 BYTE abSignatureMD4NoOID[128] = {
1580 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1581 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1582 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1583 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1584 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1585 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1586 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1587 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1588 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1589 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1590 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1591 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1592 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1593 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1594 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1595 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1597 /* md5 with hash oid */
1598 BYTE abSignatureMD5[128] = {
1599 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1600 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1601 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1602 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1603 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1604 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1605 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1606 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1607 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1608 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1609 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1610 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1611 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1612 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1613 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1614 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1616 /* md5 without hash oid */
1617 BYTE abSignatureMD5NoOID[128] = {
1618 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1619 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1620 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1621 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1622 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1623 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1624 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1625 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1626 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1627 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1628 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1629 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1630 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1631 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1632 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1633 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1635 /* sha with hash oid */
1636 BYTE abSignatureSHA[128] = {
1637 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1638 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1639 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1640 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1641 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1642 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1643 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1644 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1645 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1646 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1647 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1648 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1649 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1650 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1651 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1652 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1654 /* sha without hash oid */
1655 BYTE abSignatureSHANoOID[128] = {
1656 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1657 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1658 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1659 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1660 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1661 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1662 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1663 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1664 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1665 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1666 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1667 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1668 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1669 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1670 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1671 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1674 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1675 ok(result, "%08x\n", GetLastError());
1676 if (!result) return;
1678 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1679 ok(result, "%08x\n", GetLastError());
1680 if (!result) return;
1682 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1683 ok(result, "%08x\n", GetLastError());
1684 if (!result) return;
1686 /*check that a NULL pointer signature is correctly handled*/
1687 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1688 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1689 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1692 /* check that we get a bad signature error when the signature is too short*/
1693 SetLastError(0xdeadbeef);
1694 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1695 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1696 broken(result), /* Win9x, WinMe, NT4 */
1697 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1699 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1700 ok(result, "%08x\n", GetLastError());
1701 if (!result) return;
1703 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1704 ok(result, "%08x\n", GetLastError());
1705 if (!result) return;
1707 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1708 * the OID at all. */
1709 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1710 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1711 if (result) return;*/
1713 CryptDestroyHash(hHash);
1715 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1716 ok(result, "%08x\n", GetLastError());
1717 if (!result) return;
1719 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1720 ok(result, "%08x\n", GetLastError());
1721 if (!result) return;
1723 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1724 ok(result, "%08x\n", GetLastError());
1725 if (!result) return;
1727 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1728 ok(result, "%08x\n", GetLastError());
1729 if (!result) return;
1731 CryptDestroyHash(hHash);
1733 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1734 ok(result, "%08x\n", GetLastError());
1735 if (!result) return;
1737 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1738 ok(result, "%08x\n", GetLastError());
1739 if (!result) return;
1741 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1742 ok(result, "%08x\n", GetLastError());
1743 if (!result) return;
1745 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1746 ok(result, "%08x\n", GetLastError());
1747 if (!result) return;
1749 CryptDestroyHash(hHash);
1751 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1752 ok(result, "%08x\n", GetLastError());
1753 if (!result) return;
1755 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1756 ok(result, "%08x\n", GetLastError());
1757 if (!result) return;
1759 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1760 ok(result, "%08x\n", GetLastError());
1761 if (!result) return;
1763 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1764 ok(result, "%08x\n", GetLastError());
1765 if (!result) return;
1767 CryptDestroyHash(hHash);
1768 CryptDestroyKey(hPubSignKey);
1771 static void test_rsa_encrypt(void)
1774 BYTE abData[2048] = "Wine rocks!";
1778 /* It is allowed to use the key exchange key for encryption/decryption */
1779 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1780 ok (result, "%08x\n", GetLastError());
1781 if (!result) return;
1784 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1785 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1786 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1788 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1789 ok (result, "%08x\n", GetLastError());
1790 if (!result) return;
1792 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1793 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1796 dwLen = sizeof(DWORD);
1797 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1798 ok(result, "%08x\n", GetLastError());
1800 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1801 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1802 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1803 " got %08x\n", dwVal);
1805 /* An RSA key doesn't support salt */
1806 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1807 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
1808 "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
1810 /* The key exchange key's public key may be exported.. */
1811 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1812 ok(result, "%08x\n", GetLastError());
1813 /* but its private key may not be. */
1814 SetLastError(0xdeadbeef);
1815 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1816 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1817 broken(result), /* Win9x/NT4 */
1818 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1819 /* Setting the permissions of the key exchange key isn't allowed, either. */
1820 dwVal |= CRYPT_EXPORT;
1821 SetLastError(0xdeadbeef);
1822 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1824 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1825 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1827 CryptDestroyKey(hRSAKey);
1829 /* It is not allowed to use the signature key for encryption/decryption */
1830 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1831 ok (result, "%08x\n", GetLastError());
1832 if (!result) return;
1835 dwLen = sizeof(DWORD);
1836 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1837 ok(result, "%08x\n", GetLastError());
1839 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1840 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1841 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1842 " got %08x\n", dwVal);
1844 /* The signature key's public key may also be exported.. */
1845 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1846 ok(result, "%08x\n", GetLastError());
1847 /* but its private key may not be. */
1848 SetLastError(0xdeadbeef);
1849 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1850 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1851 broken(result), /* Win9x/NT4 */
1852 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1853 /* Setting the permissions of the signature key isn't allowed, either. */
1854 dwVal |= CRYPT_EXPORT;
1855 SetLastError(0xdeadbeef);
1856 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1858 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1859 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1862 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1863 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1865 CryptDestroyKey(hRSAKey);
1868 static void test_import_export(void)
1870 DWORD dwLen, dwDataLen, dwVal;
1871 HCRYPTKEY hPublicKey, hPrivKey;
1874 BYTE emptyKey[2048], *exported_key;
1875 static BYTE abPlainPublicKey[84] = {
1876 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1877 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1878 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1879 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1880 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1881 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1882 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1883 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1884 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1885 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1886 0x11, 0x11, 0x11, 0x11
1888 static BYTE priv_key_with_high_bit[] = {
1889 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1890 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1891 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1892 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1893 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1894 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1895 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1896 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1897 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1898 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1899 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1900 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1901 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1902 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1903 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1904 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1905 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1906 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1907 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1908 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1909 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1910 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1911 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1912 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1913 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1914 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1915 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1916 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1917 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1918 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1919 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1920 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1921 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1922 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1923 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1924 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1925 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1926 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1927 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1928 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1929 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1930 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1931 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1932 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1933 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1934 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1935 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1936 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1937 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1938 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1939 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1940 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1941 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1942 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1943 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1944 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1945 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1946 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1947 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1948 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1949 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1950 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1951 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1952 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1953 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1954 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1955 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1956 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1957 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1958 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1959 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1960 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1961 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1962 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1963 0xb6, 0x5f, 0x01, 0x5e
1965 static const BYTE expected_exported_priv_key[] = {
1966 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1967 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1968 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1969 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1970 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1971 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1972 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1973 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1974 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1975 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1976 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1977 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1978 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1979 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1980 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1981 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1982 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1983 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1984 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1985 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1986 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1987 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1988 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1989 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1990 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1991 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1992 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1993 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1994 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1995 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1996 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1997 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1998 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1999 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2000 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2001 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2002 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2003 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2004 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2005 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2006 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2007 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2008 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2009 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2010 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2011 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2012 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2013 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2014 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2015 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2016 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2017 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2018 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2019 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2020 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2021 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2022 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2023 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2024 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2025 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2026 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2027 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2028 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2029 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2030 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2031 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2032 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2033 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2034 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2035 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2036 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2037 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2038 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2039 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2040 0xb6, 0x5f, 0x01, 0x5e
2044 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2045 ok(result, "failed to import the public key\n");
2047 dwDataLen=sizeof(algID);
2048 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2049 ok(result, "failed to get the KP_ALGID from the imported public key\n");
2050 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2053 dwDataLen = sizeof(DWORD);
2054 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2055 ok(result, "%08x\n", GetLastError());
2057 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2058 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2059 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2060 " got %08x\n", dwVal);
2061 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2062 ok(result, "failed to export the fresh imported public key\n");
2063 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2064 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2066 CryptDestroyKey(hPublicKey);
2068 result = CryptImportKey(hProv, priv_key_with_high_bit,
2069 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2070 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2072 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2073 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2074 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2075 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2077 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2079 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2081 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2082 "unexpected value\n");
2084 HeapFree(GetProcessHeap(), 0, exported_key);
2086 CryptDestroyKey(hPrivKey);
2089 static void test_schannel_provider(void)
2092 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2093 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2096 SCHANNEL_ALG saSChannelAlg;
2097 CRYPT_DATA_BLOB data_blob;
2098 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2099 BYTE abTLS1Master[140] = {
2100 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2101 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2102 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2103 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2104 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2105 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2106 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2107 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2108 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2109 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2110 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2111 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2112 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2113 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2114 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2115 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2116 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2117 0xd3, 0x1e, 0x82, 0xb3
2119 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2120 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2121 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2122 BYTE abClientFinished[16] = "client finished";
2123 BYTE abData[16] = "Wine rocks!";
2125 static const BYTE abEncryptedData[16] = {
2126 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2127 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2129 static const BYTE abPRF[16] = {
2130 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2131 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2133 static const BYTE abMD5[16] = {
2134 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2135 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2138 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2141 win_skip("no PROV_RSA_SCHANNEL support\n");
2144 ok (result, "%08x\n", GetLastError());
2146 CryptReleaseContext(hProv, 0);
2148 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2149 ok (result, "%08x\n", GetLastError());
2150 if (!result) return;
2152 /* To get deterministic results, we import the TLS1 master secret (which
2153 * is typically generated from a random generator). Therefore, we need
2155 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2156 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2157 ok (result, "%08x\n", GetLastError());
2158 if (!result) return;
2160 dwLen = (DWORD)sizeof(abTLS1Master);
2161 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2162 ok (result, "%08x\n", GetLastError());
2163 if (!result) return;
2165 /* Setting the TLS1 client and server random parameters, as well as the
2166 * MAC and encryption algorithm parameters. */
2167 data_blob.cbData = 33;
2168 data_blob.pbData = abClientSecret;
2169 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2170 ok (result, "%08x\n", GetLastError());
2171 if (!result) return;
2173 data_blob.cbData = 33;
2174 data_blob.pbData = abServerSecret;
2175 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2176 ok (result, "%08x\n", GetLastError());
2177 if (!result) return;
2179 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2180 saSChannelAlg.Algid = CALG_DES;
2181 saSChannelAlg.cBits = 64;
2182 saSChannelAlg.dwFlags = 0;
2183 saSChannelAlg.dwReserved = 0;
2184 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2185 ok (result, "%08x\n", GetLastError());
2186 if (!result) return;
2188 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2189 saSChannelAlg.Algid = CALG_MD5;
2190 saSChannelAlg.cBits = 128;
2191 saSChannelAlg.dwFlags = 0;
2192 saSChannelAlg.dwReserved = 0;
2193 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2194 ok (result, "%08x\n", GetLastError());
2195 if (!result) return;
2197 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2198 * (Keys can only be derived from hashes, not from other keys.) */
2199 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2200 ok (result, "%08x\n", GetLastError());
2201 if (!result) return;
2203 /* Deriving the server write encryption key from the master hash */
2204 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2205 ok (result, "%08x\n", GetLastError());
2206 if (!result) return;
2208 /* Encrypting some data with the server write encryption key and checking the result. */
2210 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2211 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2213 /* Second test case: Test the TLS1 pseudo random number function. */
2214 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2215 ok (result, "%08x\n", GetLastError());
2216 if (!result) return;
2218 /* Set the label and seed parameters for the random number function */
2219 data_blob.cbData = 36;
2220 data_blob.pbData = abHashedHandshakes;
2221 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2222 ok (result, "%08x\n", GetLastError());
2223 if (!result) return;
2225 data_blob.cbData = 15;
2226 data_blob.pbData = abClientFinished;
2227 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2228 ok (result, "%08x\n", GetLastError());
2229 if (!result) return;
2231 /* Generate some pseudo random bytes and check if they are correct. */
2232 dwLen = (DWORD)sizeof(abData);
2233 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2234 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2235 "%08x\n", GetLastError());
2237 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2238 * Hash some data with the HMAC. Compare results. */
2239 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2240 ok (result, "%08x\n", GetLastError());
2241 if (!result) return;
2243 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2244 ok (result, "%08x\n", GetLastError());
2245 if (!result) return;
2247 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2248 ok (result, "%08x\n", GetLastError());
2249 if (!result) return;
2251 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2252 ok (result, "%08x\n", GetLastError());
2253 if (!result) return;
2255 dwLen = (DWORD)sizeof(abMD5Hash);
2256 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2257 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2259 CryptDestroyHash(hHMAC);
2260 CryptDestroyHash(hTLS1PRF);
2261 CryptDestroyHash(hMasterHash);
2262 CryptDestroyKey(hServerWriteMACKey);
2263 CryptDestroyKey(hServerWriteKey);
2264 CryptDestroyKey(hRSAKey);
2265 CryptDestroyKey(hMasterSecret);
2266 CryptReleaseContext(hProv, 0);
2267 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2270 /* Test that a key can be used to encrypt data and exported, and that, when
2271 * the exported key is imported again, can be used to decrypt the original
2274 static void test_rsa_round_trip(void)
2276 static const char test_string[] = "Well this is a fine how-do-you-do.";
2278 HCRYPTKEY signKey, keyExchangeKey;
2280 BYTE data[256], *exportedKey;
2281 DWORD dataLen, keyLen;
2283 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2284 CRYPT_DELETEKEYSET);
2286 /* Generate a new key... */
2287 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2289 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2290 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2291 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2292 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2293 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2294 /* encrypt some data with it... */
2295 memcpy(data, test_string, strlen(test_string) + 1);
2296 dataLen = strlen(test_string) + 1;
2297 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2299 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2300 "CryptEncrypt failed: %08x\n", GetLastError());
2301 /* export the key... */
2302 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2304 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2305 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2306 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2308 /* destroy the key... */
2309 CryptDestroyKey(keyExchangeKey);
2310 CryptDestroyKey(signKey);
2311 /* import the key again... */
2312 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2313 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2314 HeapFree(GetProcessHeap(), 0, exportedKey);
2315 /* and decrypt the data encrypted with the original key with the imported
2318 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2319 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2320 "CryptDecrypt failed: %08x\n", GetLastError());
2323 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2324 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2326 CryptDestroyKey(keyExchangeKey);
2327 CryptReleaseContext(prov, 0);
2329 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2330 CRYPT_DELETEKEYSET);
2333 static void test_enum_container(void)
2335 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2337 BOOL result, fFound = FALSE;
2339 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2340 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2341 SetLastError(0xdeadbeef);
2342 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2343 ok (result, "%08x\n", GetLastError());
2344 ok (dwBufferLen == MAX_PATH + 1 ||
2345 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2346 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2348 /* If the result fits into abContainerName dwBufferLen is left untouched */
2349 dwBufferLen = (DWORD)sizeof(abContainerName);
2350 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2351 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2353 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2355 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2356 dwBufferLen = (DWORD)sizeof(abContainerName);
2357 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2359 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2362 static BYTE signBlob[] = {
2363 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2364 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2365 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2366 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2367 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2368 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2369 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2370 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2371 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2372 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2373 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2374 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2375 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2376 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2377 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2378 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2379 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2380 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2381 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2382 0xb6,0x85,0x86,0x07 };
2384 static void test_null_provider(void)
2389 DWORD keySpec, dataLen,dwParam;
2390 char szName[MAX_PATH];
2392 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2393 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2394 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2395 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2396 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2397 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2398 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2399 CRYPT_DELETEKEYSET);
2400 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2401 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2402 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2403 CRYPT_DELETEKEYSET);
2404 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2405 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2406 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2407 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2408 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2410 /* Delete the default container. */
2411 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2412 /* Once you've deleted the default container you can't open it as if it
2415 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2416 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2417 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2418 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2419 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2420 CRYPT_VERIFYCONTEXT);
2421 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2422 if (!result) return;
2423 dataLen = sizeof(keySpec);
2424 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2426 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2427 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2428 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2429 * supported, you can't get the keys from this container.
2431 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2432 ok(!result && GetLastError() == NTE_NO_KEY,
2433 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2434 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2435 ok(!result && GetLastError() == NTE_NO_KEY,
2436 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2437 result = CryptReleaseContext(prov, 0);
2438 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2439 /* You can create a new default container. */
2440 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2442 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2443 /* But you still can't get the keys (until one's been generated.) */
2444 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2445 ok(!result && GetLastError() == NTE_NO_KEY,
2446 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2447 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2448 ok(!result && GetLastError() == NTE_NO_KEY,
2449 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2450 CryptReleaseContext(prov, 0);
2451 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2453 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2454 CRYPT_DELETEKEYSET);
2455 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2456 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2457 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2458 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2459 CRYPT_VERIFYCONTEXT);
2460 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2461 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2462 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2464 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2465 if (!result) return;
2466 /* Test provider parameters getter */
2467 dataLen = sizeof(dwParam);
2468 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2469 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2470 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2471 dataLen = sizeof(dwParam);
2472 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2473 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2474 "Expected 0, got 0x%08X\n",dwParam);
2475 dataLen = sizeof(dwParam);
2476 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2477 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2478 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2479 dataLen = sizeof(keySpec);
2480 SetLastError(0xdeadbeef);
2481 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2482 if (!result && GetLastError() == NTE_BAD_TYPE)
2483 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2485 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2486 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2487 /* PP_CONTAINER parameter */
2488 dataLen = sizeof(szName);
2489 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2490 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2491 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2492 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2493 /* PP_UNIQUE_CONTAINER parameter */
2494 dataLen = sizeof(szName);
2495 SetLastError(0xdeadbeef);
2496 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2497 if (!result && GetLastError() == NTE_BAD_TYPE)
2499 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2503 char container[MAX_PATH];
2505 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2506 uniquecontainer(container);
2509 ok(dataLen == strlen(container)+1 ||
2510 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2511 "Expected a param length of 70, got %d\n", dataLen);
2512 ok(!strcmp(container, szName) ||
2513 broken(!strcmp(szName, szContainer)) /* WinME */,
2514 "Wrong container name : %s\n", szName);
2517 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2518 ok(!result && GetLastError() == NTE_NO_KEY,
2519 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2520 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2521 ok(!result && GetLastError() == NTE_NO_KEY,
2522 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2524 /* Importing a key exchange blob.. */
2525 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2527 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2528 CryptDestroyKey(key);
2529 /* allows access to the key exchange key.. */
2530 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2531 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2532 CryptDestroyKey(key);
2533 /* but not to the private key. */
2534 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2535 ok(!result && GetLastError() == NTE_NO_KEY,
2536 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2537 CryptReleaseContext(prov, 0);
2538 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2539 CRYPT_DELETEKEYSET);
2541 /* Whereas importing a sign blob.. */
2542 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2544 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2545 if (!result) return;
2546 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2547 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2548 CryptDestroyKey(key);
2549 /* doesn't allow access to the key exchange key.. */
2550 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2551 ok(!result && GetLastError() == NTE_NO_KEY,
2552 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2553 /* but does to the private key. */
2554 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2555 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2556 CryptDestroyKey(key);
2557 CryptReleaseContext(prov, 0);
2559 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2560 CRYPT_DELETEKEYSET);
2562 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2563 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2565 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2566 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2567 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2568 CryptDestroyKey(key);
2569 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2570 ok(!result, "expected CryptGetUserKey to fail\n");
2571 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2572 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2573 CryptDestroyKey(key);
2574 CryptReleaseContext(prov, 0);
2576 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2577 CRYPT_DELETEKEYSET);
2579 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2580 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2582 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2583 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2584 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2585 CryptDestroyKey(key);
2586 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2587 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2588 CryptDestroyKey(key);
2589 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2590 ok(!result, "expected CryptGetUserKey to fail\n");
2591 CryptReleaseContext(prov, 0);
2593 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2594 CRYPT_DELETEKEYSET);
2596 /* test for the bug in accessing the user key in a container
2598 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2600 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2601 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2602 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2603 CryptDestroyKey(key);
2604 CryptReleaseContext(prov,0);
2605 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2606 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2607 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2608 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2609 CryptDestroyKey(key);
2610 CryptReleaseContext(prov, 0);
2612 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2613 CRYPT_DELETEKEYSET);
2615 /* test the machine key set */
2616 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2617 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2618 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2619 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2620 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2621 CryptReleaseContext(prov, 0);
2622 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2623 CRYPT_MACHINE_KEYSET);
2624 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2625 CryptReleaseContext(prov,0);
2626 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2627 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2628 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2630 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2631 CRYPT_MACHINE_KEYSET);
2632 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2633 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2637 static void test_key_permissions(void)
2639 HCRYPTKEY hKey1, hKey2;
2643 /* Create keys that are exportable */
2644 if (!init_base_environment(CRYPT_EXPORTABLE))
2647 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2648 ok (result, "%08x\n", GetLastError());
2649 if (!result) return;
2652 dwLen = sizeof(DWORD);
2653 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2654 ok(result, "%08x\n", GetLastError());
2656 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2657 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2658 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2659 " got %08x\n", dwVal);
2661 /* The key exchange key's public key may be exported.. */
2662 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2663 ok(result, "%08x\n", GetLastError());
2664 /* and its private key may be too. */
2665 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2666 ok(result, "%08x\n", GetLastError());
2667 /* Turning off the key's export permissions is "allowed".. */
2668 dwVal &= ~CRYPT_EXPORT;
2669 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2671 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2672 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2673 "%08x\n", GetLastError());
2674 /* but it has no effect. */
2676 dwLen = sizeof(DWORD);
2677 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2678 ok(result, "%08x\n", GetLastError());
2680 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2681 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2682 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2683 " got %08x\n", dwVal);
2684 /* Thus, changing the export flag of the key doesn't affect whether the key
2687 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2688 ok(result, "%08x\n", GetLastError());
2690 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2691 ok (result, "%08x\n", GetLastError());
2693 /* A subsequent get of the same key, into a different handle, also doesn't
2694 * show that the permissions have been changed.
2697 dwLen = sizeof(DWORD);
2698 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2699 ok(result, "%08x\n", GetLastError());
2701 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2702 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2703 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2704 " got %08x\n", dwVal);
2706 CryptDestroyKey(hKey2);
2707 CryptDestroyKey(hKey1);
2709 clean_up_base_environment();
2712 static void test_key_initialization(void)
2715 HCRYPTPROV prov1, prov2;
2716 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2718 static BYTE abSessionKey[148] = {
2719 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2720 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2721 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2722 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2723 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2724 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2725 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2726 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2727 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2728 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2729 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2730 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2731 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2732 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2733 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2734 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2735 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2736 0x04, 0x8c, 0x49, 0x92
2739 /* Like init_base_environment, but doesn't generate new keys, as they'll
2740 * be imported instead.
2742 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2744 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2746 ok(result, "%08x\n", GetLastError());
2748 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2749 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2751 dwLen = (DWORD)sizeof(abSessionKey);
2752 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2753 ok(result, "%08x\n", GetLastError());
2755 /* Once the key has been imported, subsequently acquiring a context with
2756 * the same name will allow retrieving the key.
2758 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2759 ok(result, "%08x\n", GetLastError());
2760 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2761 ok(result, "%08x\n", GetLastError());
2762 if (result) CryptDestroyKey(hKey);
2763 CryptReleaseContext(prov2, 0);
2765 CryptDestroyKey(hSessionKey);
2766 CryptDestroyKey(hKeyExchangeKey);
2767 CryptReleaseContext(prov1, 0);
2768 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2769 CRYPT_DELETEKEYSET);
2774 if (!init_base_environment(0))
2786 test_block_cipher_modes();
2787 test_import_private();
2788 test_verify_signature();
2790 test_import_export();
2791 test_enum_container();
2792 clean_up_base_environment();
2793 test_key_permissions();
2794 test_key_initialization();
2795 test_schannel_provider();
2796 test_null_provider();
2797 test_rsa_round_trip();
2798 if (!init_aes_environment())
2804 clean_up_aes_environment();