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, "%d, %08x\n", result, GetLastError());
133 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
135 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
136 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
137 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
139 ok(result, "%08x\n", GetLastError());
140 if (!result) return 0;
141 result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey);
142 ok(result, "%08x\n", GetLastError());
143 if (result) CryptDestroyKey(hKey);
144 result = CryptGenKey(hProv, AT_SIGNATURE, dwKeyFlags, &hKey);
145 ok(result, "%08x\n", GetLastError());
146 if (result) CryptDestroyKey(hKey);
151 static void clean_up_base_environment(void)
155 SetLastError(0xdeadbeef);
156 result = CryptReleaseContext(hProv, 1);
157 ok(!result || broken(result) /* Win98 */, "Expected failure\n");
158 ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
160 /* Just to prove that Win98 also released the CSP */
161 SetLastError(0xdeadbeef);
162 result = CryptReleaseContext(hProv, 0);
163 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
165 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
168 static int init_aes_environment(void)
173 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
175 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
177 /* we are using NULL as provider name for RSA_AES provider as the provider
178 * names are different in Windows XP and Vista. Its different as to what
179 * its defined in the SDK on Windows XP.
180 * This provider is available on Windows XP, Windows 2003 and Vista. */
182 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
183 if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
185 win_skip("RSA_AES provider not supported\n");
188 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
190 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
192 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
193 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
194 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
196 ok(result, "%08x\n", GetLastError());
197 if (!result) return 0;
198 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
199 ok(result, "%08x\n", GetLastError());
200 if (result) CryptDestroyKey(hKey);
201 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
202 ok(result, "%08x\n", GetLastError());
203 if (result) CryptDestroyKey(hKey);
208 static void clean_up_aes_environment(void)
212 result = CryptReleaseContext(hProv, 1);
213 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
215 CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
218 static void test_prov(void)
223 dwLen = (DWORD)sizeof(DWORD);
224 SetLastError(0xdeadbeef);
225 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
226 if (!result && GetLastError() == NTE_BAD_TYPE)
227 skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
229 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
231 dwLen = (DWORD)sizeof(DWORD);
232 SetLastError(0xdeadbeef);
233 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
234 if (!result && GetLastError() == NTE_BAD_TYPE)
235 skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
237 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
240 static void test_gen_random(void)
243 BYTE rnd1[16], rnd2[16];
245 memset(rnd1, 0, sizeof(rnd1));
246 memset(rnd2, 0, sizeof(rnd2));
248 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
249 if (!result && GetLastError() == NTE_FAIL) {
250 /* rsaenh compiled without OpenSSL */
254 ok(result, "%08x\n", GetLastError());
256 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
257 ok(result, "%08x\n", GetLastError());
259 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
262 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
266 unsigned char pbData[2000];
270 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
271 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
273 /* rsaenh compiled without OpenSSL */
274 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
277 ok(result, "%08x\n", GetLastError());
278 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
279 ok(result, "%08x\n", GetLastError());
280 if (!result) return FALSE;
281 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
282 ok(result, "%08x\n", GetLastError());
283 if (!result) return FALSE;
285 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
286 ok(result, "%08x\n", GetLastError());
287 CryptDestroyHash(hHash);
291 static void test_hashes(void)
293 static const unsigned char md2hash[16] = {
294 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
295 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
296 static const unsigned char md4hash[16] = {
297 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
298 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
299 static const unsigned char empty_md5hash[16] = {
300 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
301 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
302 static const unsigned char md5hash[16] = {
303 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
304 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
305 static const unsigned char sha1hash[20] = {
306 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
307 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
308 unsigned char pbData[2048];
310 HCRYPTHASH hHash, hHashClone;
311 BYTE pbHashValue[36];
315 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
318 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
320 /* rsaenh compiled without OpenSSL */
321 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
323 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
324 ok(result, "%08x\n", GetLastError());
327 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
328 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
331 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
332 ok(result, "%08x\n", GetLastError());
334 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
336 result = CryptDestroyHash(hHash);
337 ok(result, "%08x\n", GetLastError());
341 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
342 ok(result, "%08x\n", GetLastError());
344 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
345 ok(result, "%08x\n", GetLastError());
348 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
349 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
352 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
353 ok(result, "%08x\n", GetLastError());
355 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
357 result = CryptDestroyHash(hHash);
358 ok(result, "%08x\n", GetLastError());
361 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
362 ok(result, "%08x\n", GetLastError());
365 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
366 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
368 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
369 ok(result, "%08x\n", GetLastError());
372 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
373 ok(result, "%08x\n", GetLastError());
375 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
377 result = CryptDestroyHash(hHash);
378 ok(result, "%08x\n", GetLastError());
380 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
381 ok(result, "%08x\n", GetLastError());
383 /* The hash is available even if CryptHashData hasn't been called */
385 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
386 ok(result, "%08x\n", GetLastError());
388 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
390 /* It's also stable: getting it twice results in the same value */
391 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
392 ok(result, "%08x\n", GetLastError());
394 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
396 /* Can't add data after the hash been retrieved */
397 SetLastError(0xdeadbeef);
398 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
399 ok(!result, "Expected failure\n");
400 ok(GetLastError() == NTE_BAD_HASH_STATE ||
401 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
402 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
404 /* You can still retrieve the hash, its value just hasn't changed */
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 result = CryptDestroyHash(hHash);
411 ok(result, "%08x\n", GetLastError());
414 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
415 ok(result, "%08x\n", GetLastError());
417 result = CryptHashData(hHash, pbData, 5, 0);
418 ok(result, "%08x\n", GetLastError());
420 if(pCryptDuplicateHash) {
421 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
422 ok(result, "%08x\n", GetLastError());
424 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
425 ok(result, "%08x\n", GetLastError());
428 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
429 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
432 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
433 ok(result, "%08x\n", GetLastError());
435 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
437 result = CryptDestroyHash(hHashClone);
438 ok(result, "%08x\n", GetLastError());
441 result = CryptDestroyHash(hHash);
442 ok(result, "%08x\n", GetLastError());
445 static void test_block_cipher_modes(void)
447 static const BYTE plain[23] = {
448 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
449 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
450 static const BYTE ecb[24] = {
451 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
452 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
453 static const BYTE cbc[24] = {
454 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
455 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
456 static const BYTE cfb[24] = {
457 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
458 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
464 result = derive_key(CALG_RC2, &hKey, 40);
467 memcpy(abData, plain, sizeof(plain));
469 dwMode = CRYPT_MODE_ECB;
470 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
471 ok(result, "%08x\n", GetLastError());
474 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
475 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
476 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
478 SetLastError(ERROR_SUCCESS);
480 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
481 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
482 "%08x, dwLen: %d\n", GetLastError(), dwLen);
484 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
485 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
486 "%08x, dwLen: %d\n", GetLastError(), dwLen);
488 dwMode = CRYPT_MODE_CBC;
489 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
490 ok(result, "%08x\n", GetLastError());
493 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
494 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
495 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
498 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
499 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
500 "%08x, dwLen: %d\n", GetLastError(), dwLen);
502 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
503 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
504 "%08x, dwLen: %d\n", GetLastError(), dwLen);
506 dwMode = CRYPT_MODE_CFB;
507 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
508 ok(result, "%08x\n", GetLastError());
511 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
512 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
515 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
516 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
517 "%08x, dwLen: %d\n", GetLastError(), dwLen);
520 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
521 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
524 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
525 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
526 "%08x, dwLen: %d\n", GetLastError(), dwLen);
528 dwMode = CRYPT_MODE_OFB;
529 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
530 ok(result, "%08x\n", GetLastError());
533 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
534 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
536 CryptDestroyKey(hKey);
539 static void test_3des112(void)
544 unsigned char pbData[16];
547 result = derive_key(CALG_3DES_112, &hKey, 0);
549 /* rsaenh compiled without OpenSSL */
550 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
554 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
557 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
558 ok(result, "%08x\n", GetLastError());
560 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
561 ok(result, "%08x\n", GetLastError());
565 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
567 dwLen = cTestData[i].enclen;
568 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
569 ok(result, "%08x\n", GetLastError());
570 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
572 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
573 ok(result, "%08x\n", GetLastError());
574 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
575 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
576 if((dwLen != cTestData[i].enclen) ||
577 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
579 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
580 printBytes("got",pbData,dwLen);
583 result = CryptDestroyKey(hKey);
584 ok(result, "%08x\n", GetLastError());
587 static void test_des(void)
592 unsigned char pbData[16];
595 result = derive_key(CALG_DES, &hKey, 56);
597 /* rsaenh compiled without OpenSSL */
598 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
602 dwMode = CRYPT_MODE_ECB;
603 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
604 ok(result, "%08x\n", GetLastError());
606 dwLen = sizeof(DWORD);
607 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
608 ok(result, "%08x\n", GetLastError());
610 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
613 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
614 ok(result, "%08x\n", GetLastError());
616 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
617 ok(result, "%08x\n", GetLastError());
621 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
623 dwLen = cTestData[i].enclen;
624 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
625 ok(result, "%08x\n", GetLastError());
626 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
628 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
629 ok(result, "%08x\n", GetLastError());
630 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
631 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
632 if((dwLen != cTestData[i].enclen) ||
633 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
635 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
636 printBytes("got",pbData,dwLen);
640 result = CryptDestroyKey(hKey);
641 ok(result, "%08x\n", GetLastError());
644 static void test_3des(void)
649 unsigned char pbData[16];
650 static const BYTE des3[16] = {
651 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
652 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
655 result = derive_key(CALG_3DES, &hKey, 0);
658 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
661 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
662 ok(result, "%08x\n", GetLastError());
664 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
666 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
667 ok(result, "%08x\n", GetLastError());
671 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
673 dwLen = cTestData[i].enclen;
674 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
675 ok(result, "%08x\n", GetLastError());
676 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
678 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
679 ok(result, "%08x\n", GetLastError());
680 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
681 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
682 if((dwLen != cTestData[i].enclen) ||
683 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
685 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
686 printBytes("got",pbData,dwLen);
689 result = CryptDestroyKey(hKey);
690 ok(result, "%08x\n", GetLastError());
693 static void test_aes(int keylen)
698 unsigned char pbData[16];
704 result = derive_key(CALG_AES_256, &hKey, 0);
707 result = derive_key(CALG_AES_192, &hKey, 0);
711 result = derive_key(CALG_AES_128, &hKey, 0);
716 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
719 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
720 ok(result, "%08x\n", GetLastError());
722 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
723 ok(result, "%08x\n", GetLastError());
727 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
729 dwLen = cTestData[i].enclen;
730 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
731 ok(result, "%08x\n", GetLastError());
732 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
734 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
735 ok(result, "%08x\n", GetLastError());
736 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
737 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
738 if((dwLen != cTestData[i].enclen) ||
739 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
741 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
742 printBytes("got",pbData,dwLen);
745 result = CryptDestroyKey(hKey);
746 ok(result, "%08x\n", GetLastError());
749 static void test_rc2(void)
751 static const BYTE rc2_40_encrypted[16] = {
752 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
753 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
754 static const BYTE rc2_128_encrypted[] = {
755 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
760 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
762 unsigned char pbData[2000], pbHashValue[16];
765 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
768 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
770 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
772 CRYPT_INTEGER_BLOB salt;
774 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
775 ok(result, "%08x\n", GetLastError());
778 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
779 ok(result, "%08x\n", GetLastError());
781 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
782 ok(result, "%08x\n", GetLastError());
784 dwLen = sizeof(DWORD);
785 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
786 ok(result, "%08x\n", GetLastError());
788 dwMode = CRYPT_MODE_CBC;
789 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
790 ok(result, "%08x\n", GetLastError());
792 dwLen = sizeof(DWORD);
793 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
794 ok(result, "%08x\n", GetLastError());
796 dwModeBits = 0xdeadbeef;
797 dwLen = sizeof(DWORD);
798 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
799 ok(result, "%08x\n", GetLastError());
801 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
802 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
803 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
804 " got %08x\n", dwModeBits);
806 dwLen = sizeof(DWORD);
807 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
808 ok(result, "%08x\n", GetLastError());
810 dwLen = sizeof(DWORD);
811 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
812 ok(result, "%08x\n", GetLastError());
814 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
815 ok(result, "%08x\n", GetLastError());
816 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
817 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
818 HeapFree(GetProcessHeap(), 0, pbTemp);
820 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
821 ok(result, "%08x\n", GetLastError());
822 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
823 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
824 HeapFree(GetProcessHeap(), 0, pbTemp);
826 dwLen = sizeof(DWORD);
827 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
829 result = CryptDestroyHash(hHash);
830 ok(result, "%08x\n", GetLastError());
833 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
834 ok(result, "%08x\n", GetLastError());
836 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
838 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
839 ok(result, "%08x\n", GetLastError());
840 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
841 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
842 HeapFree(GetProcessHeap(), 0, pbTemp);
844 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
845 ok(result, "%08x\n", GetLastError());
847 /* What sizes salt can I set? */
848 salt.pbData = pbData;
852 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
853 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
856 SetLastError(0xdeadbeef);
857 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
859 broken(result), /* Win9x, WinMe, NT4, W2K */
860 "%08x\n", GetLastError());
862 result = CryptDestroyKey(hKey);
863 ok(result, "%08x\n", GetLastError());
866 /* Again, but test setting the effective key len */
867 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
869 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
871 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
873 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
874 ok(result, "%08x\n", GetLastError());
877 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
878 ok(result, "%08x\n", GetLastError());
880 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
881 ok(result, "%08x\n", GetLastError());
883 SetLastError(0xdeadbeef);
884 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
885 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
887 SetLastError(0xdeadbeef);
888 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
889 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
891 SetLastError(0xdeadbeef);
892 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
894 dwLen = sizeof(dwKeyLen);
895 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
896 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
897 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
898 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
901 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
902 ok(result, "%d\n", GetLastError());
904 dwLen = sizeof(dwKeyLen);
905 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
906 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
907 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
908 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
910 result = CryptDestroyHash(hHash);
911 ok(result, "%08x\n", GetLastError());
914 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
915 ok(result, "%08x\n", GetLastError());
917 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
918 "RC2 encryption failed!\n");
920 /* Oddly enough this succeeds, though it should have no effect */
922 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
923 ok(result, "%d\n", GetLastError());
925 result = CryptDestroyKey(hKey);
926 ok(result, "%08x\n", GetLastError());
930 static void test_rc4(void)
932 static const BYTE rc4[16] = {
933 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
934 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
938 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
939 unsigned char pbData[2000], *pbTemp;
940 unsigned char pszBuffer[256];
943 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
946 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
948 /* rsaenh compiled without OpenSSL */
949 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
951 CRYPT_INTEGER_BLOB salt;
953 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
954 ok(result, "%08x\n", GetLastError());
957 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
958 ok(result, "%08x\n", GetLastError());
960 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
961 ok(result, "%08x\n", GetLastError());
963 dwLen = sizeof(DWORD);
964 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
965 ok(result, "%08x\n", GetLastError());
967 dwLen = sizeof(DWORD);
968 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
969 ok(result, "%08x\n", GetLastError());
971 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
972 ok(result, "%08x\n", GetLastError());
973 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
974 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
975 HeapFree(GetProcessHeap(), 0, pbTemp);
977 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
978 ok(result, "%08x\n", GetLastError());
979 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
980 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
981 HeapFree(GetProcessHeap(), 0, pbTemp);
983 dwLen = sizeof(DWORD);
984 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
986 result = CryptDestroyHash(hHash);
987 ok(result, "%08x\n", GetLastError());
990 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
991 ok(result, "%08x\n", GetLastError());
993 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
994 ok(result, "%08x\n", GetLastError());
996 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
998 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
999 ok(result, "%08x\n", GetLastError());
1001 /* What sizes salt can I set? */
1002 salt.pbData = pbData;
1003 for (i=0; i<24; i++)
1006 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1007 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1010 SetLastError(0xdeadbeef);
1011 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1013 broken(result), /* Win9x, WinMe, NT4, W2K */
1014 "%08x\n", GetLastError());
1016 result = CryptDestroyKey(hKey);
1017 ok(result, "%08x\n", GetLastError());
1021 static void test_hmac(void) {
1025 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1026 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1029 static const BYTE hmac[16] = {
1030 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1031 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1034 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1036 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1038 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1039 ok(result, "%08x\n", GetLastError());
1040 if (!result) return;
1042 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1043 ok(result, "%08x\n", GetLastError());
1045 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1046 ok(result, "%08x\n", GetLastError());
1048 dwLen = sizeof(abData)/sizeof(BYTE);
1049 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1050 ok(result, "%08x\n", GetLastError());
1052 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1054 result = CryptDestroyHash(hHash);
1055 ok(result, "%08x\n", GetLastError());
1057 result = CryptDestroyKey(hKey);
1058 ok(result, "%08x\n", GetLastError());
1060 /* Provoke errors */
1061 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1062 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1065 static void test_mac(void) {
1070 BYTE abData[256], abEnc[264];
1071 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1074 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1075 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1077 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1080 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1081 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1083 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1084 ok(result, "%08x\n", GetLastError());
1085 if (!result) return;
1087 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1088 ok(result, "%08x\n", GetLastError());
1090 dwLen = sizeof(abData)/sizeof(BYTE);
1091 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1092 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1094 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1096 result = CryptDestroyHash(hHash);
1097 ok(result, "%08x\n", GetLastError());
1099 result = CryptDestroyKey(hKey);
1100 ok(result, "%08x\n", GetLastError());
1102 /* Provoke errors */
1103 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1105 SetLastError(0xdeadbeef);
1106 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1107 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1108 broken(result), /* Win9x, WinMe, NT4, W2K */
1109 "%08x\n", GetLastError());
1111 result = CryptDestroyKey(hKey);
1112 ok(result, "%08x\n", GetLastError());
1115 static BYTE abPlainPrivateKey[596] = {
1116 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1117 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1118 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1119 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1120 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1121 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1122 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1123 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1124 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1125 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1126 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1127 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1128 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1129 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1130 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1131 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1132 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1133 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1134 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1135 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1136 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1137 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1138 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1139 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1140 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1141 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1142 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1143 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1144 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1145 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1146 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1147 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1148 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1149 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1150 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1151 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1152 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1153 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1154 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1155 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1156 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1157 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1158 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1159 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1160 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1161 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1162 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1163 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1164 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1165 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1166 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1167 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1168 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1169 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1170 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1171 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1172 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1173 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1174 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1175 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1176 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1177 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1178 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1179 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1180 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1181 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1182 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1183 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1184 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1185 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1186 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1187 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1188 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1189 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1190 0xf2, 0x5d, 0x58, 0x07
1193 static void test_import_private(void)
1196 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1198 static BYTE abSessionKey[148] = {
1199 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1200 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1201 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1202 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1203 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1204 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1205 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1206 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1207 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1208 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1209 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1210 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1211 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1212 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1213 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1214 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1215 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1216 0x04, 0x8c, 0x49, 0x92
1218 static BYTE abEncryptedMessage[12] = {
1219 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1220 0x1c, 0xfd, 0xde, 0x71
1223 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1224 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1226 /* rsaenh compiled without OpenSSL */
1227 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1231 dwLen = (DWORD)sizeof(abSessionKey);
1232 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1233 ok(result, "%08x\n", GetLastError());
1234 if (!result) return;
1237 dwLen = sizeof(DWORD);
1238 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1239 ok(result, "%08x\n", GetLastError());
1241 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1242 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1243 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1244 " got %08x\n", dwVal);
1246 dwLen = (DWORD)sizeof(abEncryptedMessage);
1247 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1248 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1249 "%08x, len: %d\n", GetLastError(), dwLen);
1250 CryptDestroyKey(hSessionKey);
1252 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1254 dwLen = (DWORD)sizeof(abSessionKey);
1255 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1256 ok(result, "%08x\n", GetLastError());
1257 CryptDestroyKey(hSessionKey);
1258 if (!result) return;
1260 dwLen = (DWORD)sizeof(abSessionKey);
1261 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1262 ok(result, "%08x\n", GetLastError());
1263 if (!result) return;
1265 CryptDestroyKey(hSessionKey);
1266 CryptDestroyKey(hKeyExchangeKey);
1269 static void test_verify_signature(void) {
1271 HCRYPTKEY hPubSignKey;
1272 BYTE abData[] = "Wine rocks!";
1274 BYTE abPubKey[148] = {
1275 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1276 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1277 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1278 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1279 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1280 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1281 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1282 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1283 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1284 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1285 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1286 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1287 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1288 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1289 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1290 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1291 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1292 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1293 0xe1, 0x21, 0x50, 0xac
1295 /* md2 with hash oid */
1296 BYTE abSignatureMD2[128] = {
1297 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1298 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1299 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1300 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1301 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1302 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1303 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1304 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1305 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1306 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1307 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1308 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1309 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1310 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1311 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1312 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1314 /* md2 without hash oid */
1315 BYTE abSignatureMD2NoOID[128] = {
1316 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1317 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1318 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1319 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1320 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1321 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1322 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1323 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1324 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1325 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1326 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1327 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1328 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1329 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1330 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1331 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1333 /* md4 with hash oid */
1334 BYTE abSignatureMD4[128] = {
1335 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1336 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1337 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1338 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1339 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1340 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1341 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1342 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1343 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1344 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1345 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1346 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1347 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1348 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1349 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1350 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1352 /* md4 without hash oid */
1353 BYTE abSignatureMD4NoOID[128] = {
1354 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1355 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1356 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1357 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1358 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1359 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1360 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1361 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1362 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1363 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1364 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1365 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1366 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1367 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1368 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1369 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1371 /* md5 with hash oid */
1372 BYTE abSignatureMD5[128] = {
1373 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1374 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1375 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1376 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1377 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1378 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1379 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1380 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1381 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1382 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1383 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1384 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1385 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1386 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1387 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1388 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1390 /* md5 without hash oid */
1391 BYTE abSignatureMD5NoOID[128] = {
1392 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1393 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1394 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1395 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1396 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1397 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1398 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1399 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1400 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1401 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1402 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1403 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1404 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1405 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1406 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1407 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1409 /* sha with hash oid */
1410 BYTE abSignatureSHA[128] = {
1411 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1412 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1413 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1414 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1415 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1416 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1417 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1418 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1419 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1420 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1421 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1422 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1423 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1424 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1425 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1426 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1428 /* sha without hash oid */
1429 BYTE abSignatureSHANoOID[128] = {
1430 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1431 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1432 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1433 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1434 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1435 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1436 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1437 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1438 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1439 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1440 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1441 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1442 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1443 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1444 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1445 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1448 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1449 ok(result, "%08x\n", GetLastError());
1450 if (!result) return;
1452 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1453 ok(result, "%08x\n", GetLastError());
1454 if (!result) return;
1456 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1457 ok(result, "%08x\n", GetLastError());
1458 if (!result) return;
1460 /*check that a NULL pointer signature is correctly handled*/
1461 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1462 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1463 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1466 /* check that we get a bad signature error when the signature is too short*/
1467 SetLastError(0xdeadbeef);
1468 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1469 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1470 broken(result), /* Win9x, WinMe, NT4 */
1471 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1473 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1474 ok(result, "%08x\n", GetLastError());
1475 if (!result) return;
1477 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1478 ok(result, "%08x\n", GetLastError());
1479 if (!result) return;
1481 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1482 * the OID at all. */
1483 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1484 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1485 if (result) return;*/
1487 CryptDestroyHash(hHash);
1489 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1490 ok(result, "%08x\n", GetLastError());
1491 if (!result) return;
1493 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1494 ok(result, "%08x\n", GetLastError());
1495 if (!result) return;
1497 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1498 ok(result, "%08x\n", GetLastError());
1499 if (!result) return;
1501 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1502 ok(result, "%08x\n", GetLastError());
1503 if (!result) return;
1505 CryptDestroyHash(hHash);
1507 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1508 ok(result, "%08x\n", GetLastError());
1509 if (!result) return;
1511 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1512 ok(result, "%08x\n", GetLastError());
1513 if (!result) return;
1515 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1516 ok(result, "%08x\n", GetLastError());
1517 if (!result) return;
1519 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1520 ok(result, "%08x\n", GetLastError());
1521 if (!result) return;
1523 CryptDestroyHash(hHash);
1525 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1526 ok(result, "%08x\n", GetLastError());
1527 if (!result) return;
1529 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1530 ok(result, "%08x\n", GetLastError());
1531 if (!result) return;
1533 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1534 ok(result, "%08x\n", GetLastError());
1535 if (!result) return;
1537 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1538 ok(result, "%08x\n", GetLastError());
1539 if (!result) return;
1541 CryptDestroyHash(hHash);
1542 CryptDestroyKey(hPubSignKey);
1545 static void test_rsa_encrypt(void)
1548 BYTE abData[2048] = "Wine rocks!";
1552 /* It is allowed to use the key exchange key for encryption/decryption */
1553 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1554 ok (result, "%08x\n", GetLastError());
1555 if (!result) return;
1558 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1559 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1560 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1562 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1563 ok (result, "%08x\n", GetLastError());
1564 if (!result) return;
1566 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1567 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1570 dwLen = sizeof(DWORD);
1571 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1572 ok(result, "%08x\n", GetLastError());
1574 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1575 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1576 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1577 " got %08x\n", dwVal);
1579 /* The key exchange key's public key may be exported.. */
1580 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1581 ok(result, "%08x\n", GetLastError());
1582 /* but its private key may not be. */
1583 SetLastError(0xdeadbeef);
1584 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1585 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1586 broken(result), /* Win9x/NT4 */
1587 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1588 /* Setting the permissions of the key exchange key isn't allowed, either. */
1589 dwVal |= CRYPT_EXPORT;
1590 SetLastError(0xdeadbeef);
1591 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1593 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1594 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1596 CryptDestroyKey(hRSAKey);
1598 /* It is not allowed to use the signature key for encryption/decryption */
1599 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1600 ok (result, "%08x\n", GetLastError());
1601 if (!result) return;
1604 dwLen = sizeof(DWORD);
1605 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1606 ok(result, "%08x\n", GetLastError());
1608 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1609 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1610 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1611 " got %08x\n", dwVal);
1613 /* The signature key's public key may also be exported.. */
1614 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1615 ok(result, "%08x\n", GetLastError());
1616 /* but its private key may not be. */
1617 SetLastError(0xdeadbeef);
1618 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1619 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1620 broken(result), /* Win9x/NT4 */
1621 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1622 /* Setting the permissions of the signature key isn't allowed, either. */
1623 dwVal |= CRYPT_EXPORT;
1624 SetLastError(0xdeadbeef);
1625 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1627 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1628 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1631 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1632 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1634 CryptDestroyKey(hRSAKey);
1637 static void test_import_export(void)
1639 DWORD dwLen, dwDataLen, dwVal;
1640 HCRYPTKEY hPublicKey, hPrivKey;
1643 BYTE emptyKey[2048], *exported_key;
1644 static BYTE abPlainPublicKey[84] = {
1645 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1646 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1647 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1648 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1649 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1650 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1651 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1652 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1653 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1654 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1655 0x11, 0x11, 0x11, 0x11
1657 static BYTE priv_key_with_high_bit[] = {
1658 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1659 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1660 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1661 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1662 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1663 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1664 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1665 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1666 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1667 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1668 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1669 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1670 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1671 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1672 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1673 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1674 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1675 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1676 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1677 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1678 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1679 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1680 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1681 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1682 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1683 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1684 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1685 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1686 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1687 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1688 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1689 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1690 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1691 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1692 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1693 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1694 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1695 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1696 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1697 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1698 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1699 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1700 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1701 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1702 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1703 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1704 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1705 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1706 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1707 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1708 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1709 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1710 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1711 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1712 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1713 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1714 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1715 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1716 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1717 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1718 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1719 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1720 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1721 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1722 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1723 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1724 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1725 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1726 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1727 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1728 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1729 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1730 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1731 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1732 0xb6, 0x5f, 0x01, 0x5e
1734 static const BYTE expected_exported_priv_key[] = {
1735 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1736 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1737 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1738 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1739 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1740 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1741 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1742 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1743 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1744 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1745 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1746 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1747 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1748 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1749 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1750 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1751 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1752 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1753 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1754 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1755 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1756 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1757 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1758 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1759 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1760 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1761 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1762 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1763 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1764 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1765 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1766 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1767 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1768 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1769 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1770 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1771 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1772 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1773 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1774 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1775 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1776 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1777 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1778 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1779 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1780 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1781 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1782 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1783 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1784 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1785 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1786 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1787 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1788 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1789 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1790 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1791 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1792 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1793 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1794 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1795 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1796 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1797 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1798 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1799 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1800 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1801 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1802 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1803 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1804 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1805 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1806 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1807 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1808 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1809 0xb6, 0x5f, 0x01, 0x5e
1813 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1814 ok(result, "failed to import the public key\n");
1816 dwDataLen=sizeof(algID);
1817 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1818 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1819 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1822 dwDataLen = sizeof(DWORD);
1823 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
1824 ok(result, "%08x\n", GetLastError());
1826 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1827 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1828 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1829 " got %08x\n", dwVal);
1830 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1831 ok(result, "failed to export the fresh imported public key\n");
1832 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1833 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1835 CryptDestroyKey(hPublicKey);
1837 result = CryptImportKey(hProv, priv_key_with_high_bit,
1838 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
1839 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1841 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
1842 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
1843 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
1844 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
1846 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
1848 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
1850 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
1851 "unexpected value\n");
1853 HeapFree(GetProcessHeap(), 0, exported_key);
1855 CryptDestroyKey(hPrivKey);
1858 static void test_schannel_provider(void)
1861 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1862 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1865 SCHANNEL_ALG saSChannelAlg;
1866 CRYPT_DATA_BLOB data_blob;
1867 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1868 BYTE abTLS1Master[140] = {
1869 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1870 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1871 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1872 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1873 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1874 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1875 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1876 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1877 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1878 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1879 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1880 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1881 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1882 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1883 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1884 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1885 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1886 0xd3, 0x1e, 0x82, 0xb3
1888 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1889 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1890 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1891 BYTE abClientFinished[16] = "client finished";
1892 BYTE abData[16] = "Wine rocks!";
1894 static const BYTE abEncryptedData[16] = {
1895 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1896 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1898 static const BYTE abPRF[16] = {
1899 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1900 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1902 static const BYTE abMD5[16] = {
1903 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1904 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1907 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1910 win_skip("no PROV_RSA_SCHANNEL support\n");
1913 ok (result, "%08x\n", GetLastError());
1915 CryptReleaseContext(hProv, 0);
1917 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1918 ok (result, "%08x\n", GetLastError());
1919 if (!result) return;
1921 /* To get deterministic results, we import the TLS1 master secret (which
1922 * is typically generated from a random generator). Therefore, we need
1924 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1925 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1926 ok (result, "%08x\n", GetLastError());
1927 if (!result) return;
1929 dwLen = (DWORD)sizeof(abTLS1Master);
1930 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1931 ok (result, "%08x\n", GetLastError());
1932 if (!result) return;
1934 /* Setting the TLS1 client and server random parameters, as well as the
1935 * MAC and encryption algorithm parameters. */
1936 data_blob.cbData = 33;
1937 data_blob.pbData = abClientSecret;
1938 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1939 ok (result, "%08x\n", GetLastError());
1940 if (!result) return;
1942 data_blob.cbData = 33;
1943 data_blob.pbData = abServerSecret;
1944 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1945 ok (result, "%08x\n", GetLastError());
1946 if (!result) return;
1948 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1949 saSChannelAlg.Algid = CALG_DES;
1950 saSChannelAlg.cBits = 64;
1951 saSChannelAlg.dwFlags = 0;
1952 saSChannelAlg.dwReserved = 0;
1953 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1954 ok (result, "%08x\n", GetLastError());
1955 if (!result) return;
1957 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1958 saSChannelAlg.Algid = CALG_MD5;
1959 saSChannelAlg.cBits = 128;
1960 saSChannelAlg.dwFlags = 0;
1961 saSChannelAlg.dwReserved = 0;
1962 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1963 ok (result, "%08x\n", GetLastError());
1964 if (!result) return;
1966 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1967 * (Keys can only be derived from hashes, not from other keys.) */
1968 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1969 ok (result, "%08x\n", GetLastError());
1970 if (!result) return;
1972 /* Deriving the server write encryption key from the master hash */
1973 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1974 ok (result, "%08x\n", GetLastError());
1975 if (!result) return;
1977 /* Encrypting some data with the server write encryption key and checking the result. */
1979 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1980 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1982 /* Second test case: Test the TLS1 pseudo random number function. */
1983 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1984 ok (result, "%08x\n", GetLastError());
1985 if (!result) return;
1987 /* Set the label and seed parameters for the random number function */
1988 data_blob.cbData = 36;
1989 data_blob.pbData = abHashedHandshakes;
1990 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1991 ok (result, "%08x\n", GetLastError());
1992 if (!result) return;
1994 data_blob.cbData = 15;
1995 data_blob.pbData = abClientFinished;
1996 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1997 ok (result, "%08x\n", GetLastError());
1998 if (!result) return;
2000 /* Generate some pseudo random bytes and check if they are correct. */
2001 dwLen = (DWORD)sizeof(abData);
2002 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2003 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2004 "%08x\n", GetLastError());
2006 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2007 * Hash some data with the HMAC. Compare results. */
2008 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2009 ok (result, "%08x\n", GetLastError());
2010 if (!result) return;
2012 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2013 ok (result, "%08x\n", GetLastError());
2014 if (!result) return;
2016 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2017 ok (result, "%08x\n", GetLastError());
2018 if (!result) return;
2020 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2021 ok (result, "%08x\n", GetLastError());
2022 if (!result) return;
2024 dwLen = (DWORD)sizeof(abMD5Hash);
2025 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2026 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2028 CryptDestroyHash(hHMAC);
2029 CryptDestroyHash(hTLS1PRF);
2030 CryptDestroyHash(hMasterHash);
2031 CryptDestroyKey(hServerWriteMACKey);
2032 CryptDestroyKey(hServerWriteKey);
2033 CryptDestroyKey(hRSAKey);
2034 CryptDestroyKey(hMasterSecret);
2035 CryptReleaseContext(hProv, 0);
2036 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2039 /* Test that a key can be used to encrypt data and exported, and that, when
2040 * the exported key is imported again, can be used to decrypt the original
2043 static void test_rsa_round_trip(void)
2045 static const char test_string[] = "Well this is a fine how-do-you-do.";
2047 HCRYPTKEY signKey, keyExchangeKey;
2049 BYTE data[256], *exportedKey;
2050 DWORD dataLen, keyLen;
2052 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2053 CRYPT_DELETEKEYSET);
2055 /* Generate a new key... */
2056 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2058 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2059 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2060 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2061 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2062 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2063 /* encrypt some data with it... */
2064 memcpy(data, test_string, strlen(test_string) + 1);
2065 dataLen = strlen(test_string) + 1;
2066 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2068 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2069 "CryptEncrypt failed: %08x\n", GetLastError());
2070 /* export the key... */
2071 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2073 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2074 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2075 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2077 /* destroy the key... */
2078 CryptDestroyKey(keyExchangeKey);
2079 CryptDestroyKey(signKey);
2080 /* import the key again... */
2081 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2082 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2083 HeapFree(GetProcessHeap(), 0, exportedKey);
2084 /* and decrypt the data encrypted with the original key with the imported
2087 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2088 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2089 "CryptDecrypt failed: %08x\n", GetLastError());
2092 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2093 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2095 CryptDestroyKey(keyExchangeKey);
2096 CryptReleaseContext(prov, 0);
2098 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2099 CRYPT_DELETEKEYSET);
2102 static void test_enum_container(void)
2104 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2106 BOOL result, fFound = FALSE;
2108 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2109 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2110 SetLastError(0xdeadbeef);
2111 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2112 ok (result, "%08x\n", GetLastError());
2113 ok (dwBufferLen == MAX_PATH + 1 ||
2114 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2115 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2117 /* If the result fits into abContainerName dwBufferLen is left untouched */
2118 dwBufferLen = (DWORD)sizeof(abContainerName);
2119 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2120 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2122 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2124 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2125 dwBufferLen = (DWORD)sizeof(abContainerName);
2126 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2128 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2131 static BYTE signBlob[] = {
2132 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2133 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2134 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2135 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2136 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2137 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2138 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2139 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2140 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2141 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2142 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2143 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2144 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2145 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2146 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2147 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2148 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2149 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2150 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2151 0xb6,0x85,0x86,0x07 };
2153 static void test_null_provider(void)
2158 DWORD keySpec, dataLen,dwParam;
2159 char szName[MAX_PATH];
2161 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2162 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2163 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2164 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2165 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2166 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2167 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2168 CRYPT_DELETEKEYSET);
2169 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2170 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2171 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2172 CRYPT_DELETEKEYSET);
2173 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2174 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2175 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2176 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2177 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2179 /* Delete the default container. */
2180 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2181 /* Once you've deleted the default container you can't open it as if it
2184 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2185 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2186 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2187 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2188 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2189 CRYPT_VERIFYCONTEXT);
2190 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2191 if (!result) return;
2192 dataLen = sizeof(keySpec);
2193 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2195 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2196 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2197 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2198 * supported, you can't get the keys from this container.
2200 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2201 ok(!result && GetLastError() == NTE_NO_KEY,
2202 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2203 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2204 ok(!result && GetLastError() == NTE_NO_KEY,
2205 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2206 result = CryptReleaseContext(prov, 0);
2207 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2208 /* You can create a new default container. */
2209 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2211 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2212 /* But you still can't get the keys (until one's been generated.) */
2213 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2214 ok(!result && GetLastError() == NTE_NO_KEY,
2215 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2216 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2217 ok(!result && GetLastError() == NTE_NO_KEY,
2218 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2219 CryptReleaseContext(prov, 0);
2220 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2222 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2223 CRYPT_DELETEKEYSET);
2224 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2225 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2226 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2227 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2228 CRYPT_VERIFYCONTEXT);
2229 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2230 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2231 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2233 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2234 if (!result) return;
2235 /* Test provider parameters getter */
2236 dataLen = sizeof(dwParam);
2237 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2238 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2239 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2240 dataLen = sizeof(dwParam);
2241 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2242 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2243 "Expected 0, got 0x%08X\n",dwParam);
2244 dataLen = sizeof(dwParam);
2245 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2246 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2247 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2248 dataLen = sizeof(keySpec);
2249 SetLastError(0xdeadbeef);
2250 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2251 if (!result && GetLastError() == NTE_BAD_TYPE)
2252 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2254 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2255 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2256 /* PP_CONTAINER parameter */
2257 dataLen = sizeof(szName);
2258 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2259 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2260 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2261 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2262 /* PP_UNIQUE_CONTAINER parameter */
2263 dataLen = sizeof(szName);
2264 SetLastError(0xdeadbeef);
2265 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2266 if (!result && GetLastError() == NTE_BAD_TYPE)
2268 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2272 char container[MAX_PATH];
2274 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2275 uniquecontainer(container);
2278 ok(dataLen == strlen(container)+1 ||
2279 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2280 "Expected a param length of 70, got %d\n", dataLen);
2281 ok(!strcmp(container, szName) ||
2282 broken(!strcmp(szName, szContainer)) /* WinME */,
2283 "Wrong container name : %s\n", szName);
2286 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2287 ok(!result && GetLastError() == NTE_NO_KEY,
2288 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2289 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2290 ok(!result && GetLastError() == NTE_NO_KEY,
2291 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2293 /* Importing a key exchange blob.. */
2294 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2296 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2297 CryptDestroyKey(key);
2298 /* allows access to the key exchange key.. */
2299 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2300 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2301 CryptDestroyKey(key);
2302 /* but not to the private key. */
2303 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2304 ok(!result && GetLastError() == NTE_NO_KEY,
2305 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2306 CryptReleaseContext(prov, 0);
2307 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2308 CRYPT_DELETEKEYSET);
2310 /* Whereas importing a sign blob.. */
2311 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2313 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2314 if (!result) return;
2315 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2316 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2317 CryptDestroyKey(key);
2318 /* doesn't allow access to the key exchange key.. */
2319 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2320 ok(!result && GetLastError() == NTE_NO_KEY,
2321 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2322 /* but does to the private key. */
2323 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2324 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2325 CryptDestroyKey(key);
2326 CryptReleaseContext(prov, 0);
2328 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2329 CRYPT_DELETEKEYSET);
2331 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2332 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2334 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2335 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2336 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2337 CryptDestroyKey(key);
2338 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2339 ok(!result, "expected CryptGetUserKey to fail\n");
2340 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2341 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2342 CryptDestroyKey(key);
2343 CryptReleaseContext(prov, 0);
2345 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2346 CRYPT_DELETEKEYSET);
2348 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2349 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2351 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2352 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2353 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2354 CryptDestroyKey(key);
2355 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2356 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2357 CryptDestroyKey(key);
2358 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2359 ok(!result, "expected CryptGetUserKey to fail\n");
2360 CryptReleaseContext(prov, 0);
2362 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2363 CRYPT_DELETEKEYSET);
2365 /* test for the bug in accessing the user key in a container
2367 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2369 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2370 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2371 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2372 CryptDestroyKey(key);
2373 CryptReleaseContext(prov,0);
2374 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2375 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2376 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2377 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2378 CryptDestroyKey(key);
2379 CryptReleaseContext(prov, 0);
2381 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2382 CRYPT_DELETEKEYSET);
2384 /* test the machine key set */
2385 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2386 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2387 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2388 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2389 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2390 CryptReleaseContext(prov, 0);
2391 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2392 CRYPT_MACHINE_KEYSET);
2393 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2394 CryptReleaseContext(prov,0);
2395 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2396 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2397 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2399 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2400 CRYPT_MACHINE_KEYSET);
2401 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2402 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2406 static void test_key_permissions(void)
2408 HCRYPTKEY hKey1, hKey2;
2412 /* Create keys that are exportable */
2413 if (!init_base_environment(CRYPT_EXPORTABLE))
2416 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2417 ok (result, "%08x\n", GetLastError());
2418 if (!result) return;
2421 dwLen = sizeof(DWORD);
2422 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2423 ok(result, "%08x\n", GetLastError());
2425 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2426 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2427 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2428 " got %08x\n", dwVal);
2430 /* The key exchange key's public key may be exported.. */
2431 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2432 ok(result, "%08x\n", GetLastError());
2433 /* and its private key may be too. */
2434 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2435 ok(result, "%08x\n", GetLastError());
2436 /* Turning off the key's export permissions is "allowed".. */
2437 dwVal &= ~CRYPT_EXPORT;
2438 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2440 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2441 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2442 "%08x\n", GetLastError());
2443 /* but it has no effect. */
2445 dwLen = sizeof(DWORD);
2446 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2447 ok(result, "%08x\n", GetLastError());
2449 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2450 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2451 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2452 " got %08x\n", dwVal);
2453 /* Thus, changing the export flag of the key doesn't affect whether the key
2456 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2457 ok(result, "%08x\n", GetLastError());
2459 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2460 ok (result, "%08x\n", GetLastError());
2462 /* A subsequent get of the same key, into a different handle, also doesn't
2463 * show that the permissions have been changed.
2466 dwLen = sizeof(DWORD);
2467 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2468 ok(result, "%08x\n", GetLastError());
2470 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2471 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2472 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2473 " got %08x\n", dwVal);
2475 CryptDestroyKey(hKey2);
2476 CryptDestroyKey(hKey1);
2478 clean_up_base_environment();
2481 static void test_key_initialization(void)
2484 HCRYPTPROV prov1, prov2;
2485 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2487 static BYTE abSessionKey[148] = {
2488 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2489 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2490 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2491 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2492 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2493 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2494 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2495 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2496 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2497 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2498 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2499 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2500 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2501 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2502 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2503 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2504 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2505 0x04, 0x8c, 0x49, 0x92
2508 /* Like init_base_environment, but doesn't generate new keys, as they'll
2509 * be imported instead.
2511 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2513 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2515 ok(result, "%08x\n", GetLastError());
2517 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2518 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2520 dwLen = (DWORD)sizeof(abSessionKey);
2521 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2522 ok(result, "%08x\n", GetLastError());
2524 /* Once the key has been imported, subsequently acquiring a context with
2525 * the same name will allow retrieving the key.
2527 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2528 ok(result, "%08x\n", GetLastError());
2529 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2530 ok(result, "%08x\n", GetLastError());
2531 if (result) CryptDestroyKey(hKey);
2532 CryptReleaseContext(prov2, 0);
2534 CryptDestroyKey(hSessionKey);
2535 CryptDestroyKey(hKeyExchangeKey);
2536 CryptReleaseContext(prov1, 0);
2537 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2538 CRYPT_DELETEKEYSET);
2543 if (!init_base_environment(0))
2555 test_block_cipher_modes();
2556 test_import_private();
2557 test_verify_signature();
2559 test_import_export();
2560 test_enum_container();
2561 clean_up_base_environment();
2562 test_key_permissions();
2563 test_key_initialization();
2564 test_schannel_provider();
2565 test_null_provider();
2566 test_rsa_round_trip();
2567 if (!init_aes_environment())
2572 clean_up_aes_environment();