2 * Unit tests for rsaenh functions
4 * Copyright (c) 2004 Michael Jung
5 * Copyright (c) 2006 Juan Lang
6 * Copyright (c) 2007 Vijay Kiran Kamuju
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
32 static HCRYPTPROV hProv;
33 static const char szContainer[] = "winetest";
34 static const char szProvider[] = MS_ENHANCED_PROV_A;
36 typedef struct _ctdatatype {
37 unsigned char origstr[32];
38 unsigned char decstr[32];
44 static const cryptdata cTestData[4] = {
46 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
49 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
52 {'a','b','c','d','e','f','g','h',0},
55 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
60 * 1. Take the MD5 Hash of the container name (with an extra null byte)
61 * 2. Turn the hash into a 4 DWORD hex value
63 * 4. Add the MachineGuid
66 static void uniquecontainer(char *unique)
68 /* MD5 hash of "winetest\0" in 4 DWORD hex */
69 static const char szContainer_md5[] = "9d20fd8d05ed2b8455d125d0bf6d6a70";
70 static const char szCryptography[] = "Software\\Microsoft\\Cryptography";
71 static const char szMachineGuid[] = "MachineGuid";
74 DWORD size = MAX_PATH;
77 /* Get the MachineGUID */
78 ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szCryptography, 0, KEY_READ | KEY_WOW64_64KEY, &hkey);
79 if (ret == ERROR_ACCESS_DENIED)
81 /* Windows 2000 can't handle KEY_WOW64_64KEY */
82 RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
84 RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
87 lstrcpy(unique, szContainer_md5);
89 lstrcat(unique, guid);
92 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
95 printf("%s: ",heading);
97 printf("0x%02x,",pb[i]);
101 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
104 static void trace_hex(BYTE *pbData, DWORD dwLen) {
108 for (i = 0; i < dwLen-7; i+=8) {
109 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
110 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
111 pbData[i+6], pbData[i+7]);
114 for (j=0; i<dwLen; j++,i++) {
115 sprintf(szTemp+6*j, "0x%02x,\n", pbData[i]);
121 static int init_base_environment(DWORD dwKeyFlags)
126 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
128 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
130 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
131 ok(!result && (GetLastError()==NTE_BAD_FLAGS ||
132 broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */)),
133 "%d, %08x\n", result, GetLastError());
135 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
137 ok(GetLastError()==NTE_BAD_KEYSET ||
138 broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */),
139 "%08x\n", GetLastError());
140 if (GetLastError()!=NTE_BAD_KEYSET)
142 win_skip("RSA full provider not available\n");
145 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
147 ok(result, "%08x\n", GetLastError());
150 win_skip("Couldn't create crypto provider\n");
153 result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey);
154 ok(result, "%08x\n", GetLastError());
155 if (result) CryptDestroyKey(hKey);
156 result = CryptGenKey(hProv, AT_SIGNATURE, dwKeyFlags, &hKey);
157 ok(result, "%08x\n", GetLastError());
158 if (result) CryptDestroyKey(hKey);
163 static void clean_up_base_environment(void)
167 SetLastError(0xdeadbeef);
168 result = CryptReleaseContext(hProv, 1);
169 ok(!result || broken(result) /* Win98 */, "Expected failure\n");
170 ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
172 /* Just to prove that Win98 also released the CSP */
173 SetLastError(0xdeadbeef);
174 result = CryptReleaseContext(hProv, 0);
175 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
177 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
180 static int init_aes_environment(void)
185 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
187 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
189 /* we are using NULL as provider name for RSA_AES provider as the provider
190 * names are different in Windows XP and Vista. Its different as to what
191 * its defined in the SDK on Windows XP.
192 * This provider is available on Windows XP, Windows 2003 and Vista. */
194 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
195 if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
197 win_skip("RSA_AES provider not supported\n");
200 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
202 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
204 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
205 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
206 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
208 ok(result, "%08x\n", GetLastError());
209 if (!result) return 0;
210 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
211 ok(result, "%08x\n", GetLastError());
212 if (result) CryptDestroyKey(hKey);
213 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
214 ok(result, "%08x\n", GetLastError());
215 if (result) CryptDestroyKey(hKey);
220 static void clean_up_aes_environment(void)
224 result = CryptReleaseContext(hProv, 1);
225 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
227 CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
230 static void test_prov(void)
235 dwLen = (DWORD)sizeof(DWORD);
236 SetLastError(0xdeadbeef);
237 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
238 if (!result && GetLastError() == NTE_BAD_TYPE)
239 skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
241 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
243 dwLen = (DWORD)sizeof(DWORD);
244 SetLastError(0xdeadbeef);
245 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
246 if (!result && GetLastError() == NTE_BAD_TYPE)
247 skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
249 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
252 static void test_gen_random(void)
255 BYTE rnd1[16], rnd2[16];
257 memset(rnd1, 0, sizeof(rnd1));
258 memset(rnd2, 0, sizeof(rnd2));
260 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
261 if (!result && GetLastError() == NTE_FAIL) {
262 /* rsaenh compiled without OpenSSL */
266 ok(result, "%08x\n", GetLastError());
268 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
269 ok(result, "%08x\n", GetLastError());
271 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
274 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
278 unsigned char pbData[2000];
282 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
283 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
285 /* rsaenh compiled without OpenSSL */
286 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
289 ok(result, "%08x\n", GetLastError());
290 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
291 ok(result, "%08x\n", GetLastError());
292 if (!result) return FALSE;
293 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
294 ok(result, "%08x\n", GetLastError());
295 if (!result) return FALSE;
297 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
298 ok(result, "%08x\n", GetLastError());
299 CryptDestroyHash(hHash);
303 static void test_hashes(void)
305 static const unsigned char md2hash[16] = {
306 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
307 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
308 static const unsigned char md4hash[16] = {
309 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
310 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
311 static const unsigned char empty_md5hash[16] = {
312 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
313 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
314 static const unsigned char md5hash[16] = {
315 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
316 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
317 static const unsigned char sha1hash[20] = {
318 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
319 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
320 unsigned char pbData[2048];
322 HCRYPTHASH hHash, hHashClone;
323 BYTE pbHashValue[36];
327 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
330 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
332 /* rsaenh compiled without OpenSSL */
333 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
335 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
336 ok(result, "%08x\n", GetLastError());
339 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
340 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
343 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
344 ok(result, "%08x\n", GetLastError());
346 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
348 result = CryptDestroyHash(hHash);
349 ok(result, "%08x\n", GetLastError());
353 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
354 ok(result, "%08x\n", GetLastError());
356 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
357 ok(result, "%08x\n", GetLastError());
360 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
361 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
364 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
365 ok(result, "%08x\n", GetLastError());
367 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
369 result = CryptDestroyHash(hHash);
370 ok(result, "%08x\n", GetLastError());
373 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
374 ok(result, "%08x\n", GetLastError());
377 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
378 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
380 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
381 ok(result, "%08x\n", GetLastError());
384 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
385 ok(result, "%08x\n", GetLastError());
387 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
389 result = CryptDestroyHash(hHash);
390 ok(result, "%08x\n", GetLastError());
392 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
393 ok(result, "%08x\n", GetLastError());
395 /* The hash is available even if CryptHashData hasn't been called */
397 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
398 ok(result, "%08x\n", GetLastError());
400 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
402 /* It's also stable: getting it twice results in the same value */
403 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
404 ok(result, "%08x\n", GetLastError());
406 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
408 /* Can't add data after the hash been retrieved */
409 SetLastError(0xdeadbeef);
410 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
411 ok(!result, "Expected failure\n");
412 ok(GetLastError() == NTE_BAD_HASH_STATE ||
413 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
414 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
416 /* You can still retrieve the hash, its value just hasn't changed */
417 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
418 ok(result, "%08x\n", GetLastError());
420 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
422 result = CryptDestroyHash(hHash);
423 ok(result, "%08x\n", GetLastError());
426 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
427 ok(result, "%08x\n", GetLastError());
429 result = CryptHashData(hHash, pbData, 5, 0);
430 ok(result, "%08x\n", GetLastError());
432 if(pCryptDuplicateHash) {
433 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
434 ok(result, "%08x\n", GetLastError());
436 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
437 ok(result, "%08x\n", GetLastError());
440 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
441 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
444 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
445 ok(result, "%08x\n", GetLastError());
447 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
449 result = CryptDestroyHash(hHashClone);
450 ok(result, "%08x\n", GetLastError());
453 result = CryptDestroyHash(hHash);
454 ok(result, "%08x\n", GetLastError());
456 /* The SHA-2 variants aren't supported in the RSA full provider */
457 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
458 ok(!result && GetLastError() == NTE_BAD_ALGID,
459 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
460 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
461 ok(!result && GetLastError() == NTE_BAD_ALGID,
462 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
463 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
464 ok(!result && GetLastError() == NTE_BAD_ALGID,
465 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
468 static void test_block_cipher_modes(void)
470 static const BYTE plain[23] = {
471 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
472 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
473 static const BYTE ecb[24] = {
474 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
475 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
476 static const BYTE cbc[24] = {
477 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
478 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
479 static const BYTE cfb[24] = {
480 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
481 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
487 result = derive_key(CALG_RC2, &hKey, 40);
490 memcpy(abData, plain, sizeof(plain));
492 dwMode = CRYPT_MODE_ECB;
493 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
494 ok(result, "%08x\n", GetLastError());
497 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
498 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
499 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
501 SetLastError(ERROR_SUCCESS);
503 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
504 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
505 "%08x, dwLen: %d\n", GetLastError(), dwLen);
507 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
508 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
509 "%08x, dwLen: %d\n", GetLastError(), dwLen);
511 dwMode = CRYPT_MODE_CBC;
512 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
513 ok(result, "%08x\n", GetLastError());
516 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
517 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
518 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
521 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
522 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
523 "%08x, dwLen: %d\n", GetLastError(), dwLen);
525 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
526 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
527 "%08x, dwLen: %d\n", GetLastError(), dwLen);
529 dwMode = CRYPT_MODE_CFB;
530 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
531 ok(result, "%08x\n", GetLastError());
534 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
535 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
538 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
539 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
540 "%08x, dwLen: %d\n", GetLastError(), dwLen);
543 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
544 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
547 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
548 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
549 "%08x, dwLen: %d\n", GetLastError(), dwLen);
551 dwMode = CRYPT_MODE_OFB;
552 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
553 ok(result, "%08x\n", GetLastError());
556 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
557 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
559 CryptDestroyKey(hKey);
562 static void test_3des112(void)
567 unsigned char pbData[16];
570 result = derive_key(CALG_3DES_112, &hKey, 0);
572 /* rsaenh compiled without OpenSSL */
573 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
577 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
580 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
581 ok(result, "%08x\n", GetLastError());
583 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
584 ok(result, "%08x\n", GetLastError());
588 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
590 dwLen = cTestData[i].enclen;
591 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
592 ok(result, "%08x\n", GetLastError());
593 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
595 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
596 ok(result, "%08x\n", GetLastError());
597 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
598 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
599 if((dwLen != cTestData[i].enclen) ||
600 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
602 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
603 printBytes("got",pbData,dwLen);
606 result = CryptDestroyKey(hKey);
607 ok(result, "%08x\n", GetLastError());
610 static void test_des(void)
615 unsigned char pbData[16];
618 result = derive_key(CALG_DES, &hKey, 56);
620 /* rsaenh compiled without OpenSSL */
621 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
625 dwMode = CRYPT_MODE_ECB;
626 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
627 ok(result, "%08x\n", GetLastError());
629 dwLen = sizeof(DWORD);
630 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
631 ok(result, "%08x\n", GetLastError());
633 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
636 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
637 ok(result, "%08x\n", GetLastError());
639 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
640 ok(result, "%08x\n", GetLastError());
644 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
646 dwLen = cTestData[i].enclen;
647 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
648 ok(result, "%08x\n", GetLastError());
649 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
651 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
652 ok(result, "%08x\n", GetLastError());
653 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
654 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
655 if((dwLen != cTestData[i].enclen) ||
656 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
658 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
659 printBytes("got",pbData,dwLen);
663 result = CryptDestroyKey(hKey);
664 ok(result, "%08x\n", GetLastError());
667 static void test_3des(void)
672 unsigned char pbData[16];
673 static const BYTE des3[16] = {
674 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
675 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
678 result = derive_key(CALG_3DES, &hKey, 0);
681 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
684 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
685 ok(result, "%08x\n", GetLastError());
687 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
689 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
690 ok(result, "%08x\n", GetLastError());
694 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
696 dwLen = cTestData[i].enclen;
697 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
698 ok(result, "%08x\n", GetLastError());
699 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
701 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
702 ok(result, "%08x\n", GetLastError());
703 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
704 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
705 if((dwLen != cTestData[i].enclen) ||
706 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
708 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
709 printBytes("got",pbData,dwLen);
712 result = CryptDestroyKey(hKey);
713 ok(result, "%08x\n", GetLastError());
716 static void test_aes(int keylen)
721 unsigned char pbData[16];
727 result = derive_key(CALG_AES_256, &hKey, 0);
730 result = derive_key(CALG_AES_192, &hKey, 0);
734 result = derive_key(CALG_AES_128, &hKey, 0);
739 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
742 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
743 ok(result, "%08x\n", GetLastError());
745 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
746 ok(result, "%08x\n", GetLastError());
750 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
752 dwLen = cTestData[i].enclen;
753 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
754 ok(result, "%08x\n", GetLastError());
755 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
757 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
758 ok(result, "%08x\n", GetLastError());
759 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
760 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
761 if((dwLen != cTestData[i].enclen) ||
762 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
764 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
765 printBytes("got",pbData,dwLen);
768 result = CryptDestroyKey(hKey);
769 ok(result, "%08x\n", GetLastError());
772 static void test_sha2(void)
774 static const unsigned char sha256hash[32] = {
775 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
776 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
777 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
780 static const unsigned char sha384hash[48] = {
781 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
782 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
783 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
784 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
785 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
787 static const unsigned char sha512hash[64] = {
788 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
789 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
790 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
791 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
792 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
793 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
794 0xb7, 0xf4, 0x81, 0xd4
796 unsigned char pbData[2048];
799 BYTE pbHashValue[64];
803 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
806 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
807 ok(result, "%08x\n", GetLastError());
810 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
811 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
813 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
814 ok(result, "%08x\n", GetLastError());
817 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
818 ok(result, "%08x\n", GetLastError());
820 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
822 result = CryptDestroyHash(hHash);
823 ok(result, "%08x\n", GetLastError());
827 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
828 ok(result, "%08x\n", GetLastError());
831 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
832 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
834 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
835 ok(result, "%08x\n", GetLastError());
838 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
839 ok(result, "%08x\n", GetLastError());
841 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
843 result = CryptDestroyHash(hHash);
844 ok(result, "%08x\n", GetLastError());
848 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
849 ok(result, "%08x\n", GetLastError());
852 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
853 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
855 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
856 ok(result, "%08x\n", GetLastError());
859 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
860 ok(result, "%08x\n", GetLastError());
862 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
864 result = CryptDestroyHash(hHash);
865 ok(result, "%08x\n", GetLastError());
869 static void test_rc2(void)
871 static const BYTE rc2_40_encrypted[16] = {
872 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
873 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
874 static const BYTE rc2_128_encrypted[] = {
875 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
880 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
882 unsigned char pbData[2000], pbHashValue[16];
885 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
888 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
890 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
892 CRYPT_INTEGER_BLOB salt;
894 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
895 ok(result, "%08x\n", GetLastError());
898 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
899 ok(result, "%08x\n", GetLastError());
901 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
902 ok(result, "%08x\n", GetLastError());
904 dwLen = sizeof(DWORD);
905 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
906 ok(result, "%08x\n", GetLastError());
908 dwMode = CRYPT_MODE_CBC;
909 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
910 ok(result, "%08x\n", GetLastError());
912 dwLen = sizeof(DWORD);
913 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
914 ok(result, "%08x\n", GetLastError());
916 dwModeBits = 0xdeadbeef;
917 dwLen = sizeof(DWORD);
918 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
919 ok(result, "%08x\n", GetLastError());
921 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
922 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
923 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
924 " got %08x\n", dwModeBits);
926 dwLen = sizeof(DWORD);
927 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
928 ok(result, "%08x\n", GetLastError());
930 dwLen = sizeof(DWORD);
931 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
932 ok(result, "%08x\n", GetLastError());
934 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
935 ok(result, "%08x\n", GetLastError());
936 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
937 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
938 HeapFree(GetProcessHeap(), 0, pbTemp);
940 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
941 ok(result, "%08x\n", GetLastError());
942 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
943 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
944 HeapFree(GetProcessHeap(), 0, pbTemp);
946 dwLen = sizeof(DWORD);
947 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
949 result = CryptDestroyHash(hHash);
950 ok(result, "%08x\n", GetLastError());
953 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
954 ok(result, "%08x\n", GetLastError());
956 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
958 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
959 ok(result, "%08x\n", GetLastError());
960 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
961 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
962 HeapFree(GetProcessHeap(), 0, pbTemp);
964 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
965 ok(result, "%08x\n", GetLastError());
967 /* What sizes salt can I set? */
968 salt.pbData = pbData;
972 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
973 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
976 SetLastError(0xdeadbeef);
977 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
979 broken(result), /* Win9x, WinMe, NT4, W2K */
980 "%08x\n", GetLastError());
982 result = CryptDestroyKey(hKey);
983 ok(result, "%08x\n", GetLastError());
986 /* Again, but test setting the effective key len */
987 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
989 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
991 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
993 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
994 ok(result, "%08x\n", GetLastError());
997 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
998 ok(result, "%08x\n", GetLastError());
1000 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1001 ok(result, "%08x\n", GetLastError());
1003 SetLastError(0xdeadbeef);
1004 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1005 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1007 SetLastError(0xdeadbeef);
1008 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1009 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1011 SetLastError(0xdeadbeef);
1012 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1014 dwLen = sizeof(dwKeyLen);
1015 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1016 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1017 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1018 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1021 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1022 ok(result, "%d\n", GetLastError());
1024 dwLen = sizeof(dwKeyLen);
1025 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1026 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1027 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1028 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1030 result = CryptDestroyHash(hHash);
1031 ok(result, "%08x\n", GetLastError());
1034 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1035 ok(result, "%08x\n", GetLastError());
1037 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1038 "RC2 encryption failed!\n");
1040 /* Oddly enough this succeeds, though it should have no effect */
1042 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1043 ok(result, "%d\n", GetLastError());
1045 result = CryptDestroyKey(hKey);
1046 ok(result, "%08x\n", GetLastError());
1050 static void test_rc4(void)
1052 static const BYTE rc4[16] = {
1053 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1054 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1058 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1059 unsigned char pbData[2000], *pbTemp;
1060 unsigned char pszBuffer[256];
1063 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1066 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1068 /* rsaenh compiled without OpenSSL */
1069 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1071 CRYPT_INTEGER_BLOB salt;
1073 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1074 ok(result, "%08x\n", GetLastError());
1077 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1078 ok(result, "%08x\n", GetLastError());
1080 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1081 ok(result, "%08x\n", GetLastError());
1083 dwLen = sizeof(DWORD);
1084 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1085 ok(result, "%08x\n", GetLastError());
1087 dwLen = sizeof(DWORD);
1088 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1089 ok(result, "%08x\n", GetLastError());
1091 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1092 ok(result, "%08x\n", GetLastError());
1093 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1094 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1095 HeapFree(GetProcessHeap(), 0, pbTemp);
1097 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1098 ok(result, "%08x\n", GetLastError());
1099 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1100 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1101 HeapFree(GetProcessHeap(), 0, pbTemp);
1103 dwLen = sizeof(DWORD);
1104 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1106 result = CryptDestroyHash(hHash);
1107 ok(result, "%08x\n", GetLastError());
1110 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1111 ok(result, "%08x\n", GetLastError());
1113 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1114 ok(result, "%08x\n", GetLastError());
1116 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1118 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1119 ok(result, "%08x\n", GetLastError());
1121 /* What sizes salt can I set? */
1122 salt.pbData = pbData;
1123 for (i=0; i<24; i++)
1126 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1127 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1130 SetLastError(0xdeadbeef);
1131 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1133 broken(result), /* Win9x, WinMe, NT4, W2K */
1134 "%08x\n", GetLastError());
1136 result = CryptDestroyKey(hKey);
1137 ok(result, "%08x\n", GetLastError());
1141 static void test_hmac(void) {
1145 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1146 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1149 static const BYTE hmac[16] = {
1150 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1151 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1154 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1156 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1158 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1159 ok(result, "%08x\n", GetLastError());
1160 if (!result) return;
1162 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1163 ok(result, "%08x\n", GetLastError());
1165 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1166 ok(result, "%08x\n", GetLastError());
1168 dwLen = sizeof(abData)/sizeof(BYTE);
1169 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1170 ok(result, "%08x\n", GetLastError());
1172 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1174 result = CryptDestroyHash(hHash);
1175 ok(result, "%08x\n", GetLastError());
1177 result = CryptDestroyKey(hKey);
1178 ok(result, "%08x\n", GetLastError());
1180 /* Provoke errors */
1181 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1182 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1185 static void test_mac(void) {
1190 BYTE abData[256], abEnc[264];
1191 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1194 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1195 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1197 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1200 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1201 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1203 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1204 ok(result, "%08x\n", GetLastError());
1205 if (!result) return;
1207 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1208 ok(result, "%08x\n", GetLastError());
1210 dwLen = sizeof(abData)/sizeof(BYTE);
1211 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1212 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1214 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1216 result = CryptDestroyHash(hHash);
1217 ok(result, "%08x\n", GetLastError());
1219 result = CryptDestroyKey(hKey);
1220 ok(result, "%08x\n", GetLastError());
1222 /* Provoke errors */
1223 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1225 SetLastError(0xdeadbeef);
1226 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1227 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1228 broken(result), /* Win9x, WinMe, NT4, W2K */
1229 "%08x\n", GetLastError());
1231 result = CryptDestroyKey(hKey);
1232 ok(result, "%08x\n", GetLastError());
1235 static BYTE abPlainPrivateKey[596] = {
1236 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1237 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1238 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1239 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1240 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1241 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1242 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1243 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1244 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1245 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1246 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1247 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1248 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1249 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1250 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1251 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1252 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1253 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1254 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1255 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1256 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1257 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1258 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1259 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1260 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1261 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1262 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1263 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1264 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1265 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1266 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1267 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1268 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1269 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1270 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1271 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1272 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1273 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1274 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1275 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1276 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1277 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1278 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1279 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1280 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1281 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1282 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1283 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1284 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1285 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1286 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1287 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1288 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1289 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1290 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1291 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1292 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1293 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1294 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1295 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1296 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1297 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1298 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1299 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1300 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1301 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1302 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1303 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1304 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1305 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1306 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1307 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1308 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1309 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1310 0xf2, 0x5d, 0x58, 0x07
1313 static void test_import_private(void)
1316 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1318 static BYTE abSessionKey[148] = {
1319 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1320 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1321 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1322 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1323 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1324 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1325 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1326 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1327 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1328 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1329 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1330 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1331 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1332 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1333 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1334 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1335 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1336 0x04, 0x8c, 0x49, 0x92
1338 static BYTE abEncryptedMessage[12] = {
1339 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1340 0x1c, 0xfd, 0xde, 0x71
1343 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1344 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1346 /* rsaenh compiled without OpenSSL */
1347 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1351 dwLen = (DWORD)sizeof(abSessionKey);
1352 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1353 ok(result, "%08x\n", GetLastError());
1354 if (!result) return;
1357 dwLen = sizeof(DWORD);
1358 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1359 ok(result, "%08x\n", GetLastError());
1361 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1362 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1363 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1364 " got %08x\n", dwVal);
1366 dwLen = (DWORD)sizeof(abEncryptedMessage);
1367 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1368 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1369 "%08x, len: %d\n", GetLastError(), dwLen);
1370 CryptDestroyKey(hSessionKey);
1372 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1374 dwLen = (DWORD)sizeof(abSessionKey);
1375 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1376 ok(result, "%08x\n", GetLastError());
1377 CryptDestroyKey(hSessionKey);
1378 if (!result) return;
1380 dwLen = (DWORD)sizeof(abSessionKey);
1381 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1382 ok(result, "%08x\n", GetLastError());
1383 if (!result) return;
1385 CryptDestroyKey(hSessionKey);
1386 CryptDestroyKey(hKeyExchangeKey);
1389 static void test_verify_signature(void) {
1391 HCRYPTKEY hPubSignKey;
1392 BYTE abData[] = "Wine rocks!";
1394 BYTE abPubKey[148] = {
1395 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1396 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1397 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1398 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1399 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1400 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1401 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1402 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1403 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1404 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1405 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1406 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1407 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1408 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1409 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1410 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1411 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1412 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1413 0xe1, 0x21, 0x50, 0xac
1415 /* md2 with hash oid */
1416 BYTE abSignatureMD2[128] = {
1417 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1418 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1419 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1420 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1421 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1422 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1423 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1424 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1425 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1426 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1427 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1428 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1429 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1430 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1431 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1432 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1434 /* md2 without hash oid */
1435 BYTE abSignatureMD2NoOID[128] = {
1436 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1437 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1438 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1439 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1440 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1441 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1442 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1443 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1444 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1445 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1446 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1447 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1448 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1449 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1450 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1451 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1453 /* md4 with hash oid */
1454 BYTE abSignatureMD4[128] = {
1455 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1456 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1457 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1458 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1459 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1460 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1461 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1462 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1463 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1464 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1465 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1466 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1467 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1468 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1469 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1470 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1472 /* md4 without hash oid */
1473 BYTE abSignatureMD4NoOID[128] = {
1474 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1475 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1476 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1477 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1478 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1479 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1480 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1481 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1482 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1483 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1484 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1485 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1486 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1487 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1488 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1489 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1491 /* md5 with hash oid */
1492 BYTE abSignatureMD5[128] = {
1493 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1494 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1495 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1496 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1497 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1498 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1499 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1500 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1501 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1502 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1503 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1504 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1505 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1506 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1507 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1508 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1510 /* md5 without hash oid */
1511 BYTE abSignatureMD5NoOID[128] = {
1512 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1513 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1514 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1515 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1516 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1517 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1518 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1519 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1520 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1521 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1522 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1523 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1524 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1525 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1526 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1527 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1529 /* sha with hash oid */
1530 BYTE abSignatureSHA[128] = {
1531 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1532 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1533 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1534 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1535 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1536 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1537 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1538 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1539 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1540 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1541 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1542 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1543 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1544 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1545 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1546 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1548 /* sha without hash oid */
1549 BYTE abSignatureSHANoOID[128] = {
1550 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1551 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1552 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1553 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1554 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1555 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1556 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1557 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1558 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1559 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1560 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1561 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1562 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1563 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1564 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1565 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1568 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1569 ok(result, "%08x\n", GetLastError());
1570 if (!result) return;
1572 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1573 ok(result, "%08x\n", GetLastError());
1574 if (!result) return;
1576 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1577 ok(result, "%08x\n", GetLastError());
1578 if (!result) return;
1580 /*check that a NULL pointer signature is correctly handled*/
1581 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1582 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1583 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1586 /* check that we get a bad signature error when the signature is too short*/
1587 SetLastError(0xdeadbeef);
1588 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1589 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1590 broken(result), /* Win9x, WinMe, NT4 */
1591 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1593 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1594 ok(result, "%08x\n", GetLastError());
1595 if (!result) return;
1597 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1598 ok(result, "%08x\n", GetLastError());
1599 if (!result) return;
1601 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1602 * the OID at all. */
1603 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1604 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1605 if (result) return;*/
1607 CryptDestroyHash(hHash);
1609 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1610 ok(result, "%08x\n", GetLastError());
1611 if (!result) return;
1613 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1614 ok(result, "%08x\n", GetLastError());
1615 if (!result) return;
1617 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1618 ok(result, "%08x\n", GetLastError());
1619 if (!result) return;
1621 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1622 ok(result, "%08x\n", GetLastError());
1623 if (!result) return;
1625 CryptDestroyHash(hHash);
1627 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1628 ok(result, "%08x\n", GetLastError());
1629 if (!result) return;
1631 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1632 ok(result, "%08x\n", GetLastError());
1633 if (!result) return;
1635 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1636 ok(result, "%08x\n", GetLastError());
1637 if (!result) return;
1639 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1640 ok(result, "%08x\n", GetLastError());
1641 if (!result) return;
1643 CryptDestroyHash(hHash);
1645 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1646 ok(result, "%08x\n", GetLastError());
1647 if (!result) return;
1649 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1650 ok(result, "%08x\n", GetLastError());
1651 if (!result) return;
1653 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1654 ok(result, "%08x\n", GetLastError());
1655 if (!result) return;
1657 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1658 ok(result, "%08x\n", GetLastError());
1659 if (!result) return;
1661 CryptDestroyHash(hHash);
1662 CryptDestroyKey(hPubSignKey);
1665 static void test_rsa_encrypt(void)
1668 BYTE abData[2048] = "Wine rocks!";
1672 /* It is allowed to use the key exchange key for encryption/decryption */
1673 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1674 ok (result, "%08x\n", GetLastError());
1675 if (!result) return;
1678 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1679 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1680 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1682 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1683 ok (result, "%08x\n", GetLastError());
1684 if (!result) return;
1686 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1687 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1690 dwLen = sizeof(DWORD);
1691 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1692 ok(result, "%08x\n", GetLastError());
1694 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1695 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1696 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1697 " got %08x\n", dwVal);
1699 /* The key exchange key's public key may be exported.. */
1700 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1701 ok(result, "%08x\n", GetLastError());
1702 /* but its private key may not be. */
1703 SetLastError(0xdeadbeef);
1704 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1705 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1706 broken(result), /* Win9x/NT4 */
1707 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1708 /* Setting the permissions of the key exchange key isn't allowed, either. */
1709 dwVal |= CRYPT_EXPORT;
1710 SetLastError(0xdeadbeef);
1711 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1713 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1714 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1716 CryptDestroyKey(hRSAKey);
1718 /* It is not allowed to use the signature key for encryption/decryption */
1719 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1720 ok (result, "%08x\n", GetLastError());
1721 if (!result) return;
1724 dwLen = sizeof(DWORD);
1725 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1726 ok(result, "%08x\n", GetLastError());
1728 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1729 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1730 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1731 " got %08x\n", dwVal);
1733 /* The signature key's public key may also be exported.. */
1734 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1735 ok(result, "%08x\n", GetLastError());
1736 /* but its private key may not be. */
1737 SetLastError(0xdeadbeef);
1738 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1739 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1740 broken(result), /* Win9x/NT4 */
1741 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1742 /* Setting the permissions of the signature key isn't allowed, either. */
1743 dwVal |= CRYPT_EXPORT;
1744 SetLastError(0xdeadbeef);
1745 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1747 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1748 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1751 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1752 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1754 CryptDestroyKey(hRSAKey);
1757 static void test_import_export(void)
1759 DWORD dwLen, dwDataLen, dwVal;
1760 HCRYPTKEY hPublicKey, hPrivKey;
1763 BYTE emptyKey[2048], *exported_key;
1764 static BYTE abPlainPublicKey[84] = {
1765 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1766 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1767 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1768 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1769 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1770 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1771 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1772 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1773 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1774 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1775 0x11, 0x11, 0x11, 0x11
1777 static BYTE priv_key_with_high_bit[] = {
1778 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1779 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1780 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1781 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1782 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1783 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1784 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1785 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1786 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1787 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1788 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1789 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1790 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1791 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1792 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1793 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1794 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1795 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1796 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1797 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1798 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1799 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1800 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1801 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1802 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1803 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1804 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1805 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1806 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1807 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1808 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1809 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1810 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1811 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1812 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1813 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1814 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1815 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1816 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1817 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1818 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1819 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1820 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1821 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1822 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1823 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1824 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1825 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1826 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1827 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1828 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1829 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1830 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1831 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1832 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1833 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1834 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1835 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1836 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1837 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1838 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1839 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1840 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1841 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1842 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1843 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1844 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1845 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1846 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1847 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1848 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1849 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1850 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1851 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1852 0xb6, 0x5f, 0x01, 0x5e
1854 static const BYTE expected_exported_priv_key[] = {
1855 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1856 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1857 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1858 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1859 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1860 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1861 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1862 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1863 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1864 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1865 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1866 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1867 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1868 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1869 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1870 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1871 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1872 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1873 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1874 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1875 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1876 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1877 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1878 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1879 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1880 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1881 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1882 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1883 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1884 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1885 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1886 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1887 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1888 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1889 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1890 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1891 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1892 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1893 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1894 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1895 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1896 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1897 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1898 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1899 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1900 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1901 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1902 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1903 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1904 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1905 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1906 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1907 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1908 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1909 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1910 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1911 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1912 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1913 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1914 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1915 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1916 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1917 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1918 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1919 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1920 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1921 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1922 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1923 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1924 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1925 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1926 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1927 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1928 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1929 0xb6, 0x5f, 0x01, 0x5e
1933 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1934 ok(result, "failed to import the public key\n");
1936 dwDataLen=sizeof(algID);
1937 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1938 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1939 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1942 dwDataLen = sizeof(DWORD);
1943 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
1944 ok(result, "%08x\n", GetLastError());
1946 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1947 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1948 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1949 " got %08x\n", dwVal);
1950 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1951 ok(result, "failed to export the fresh imported public key\n");
1952 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1953 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1955 CryptDestroyKey(hPublicKey);
1957 result = CryptImportKey(hProv, priv_key_with_high_bit,
1958 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
1959 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1961 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
1962 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
1963 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
1964 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
1966 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
1968 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
1970 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
1971 "unexpected value\n");
1973 HeapFree(GetProcessHeap(), 0, exported_key);
1975 CryptDestroyKey(hPrivKey);
1978 static void test_schannel_provider(void)
1981 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1982 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1985 SCHANNEL_ALG saSChannelAlg;
1986 CRYPT_DATA_BLOB data_blob;
1987 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1988 BYTE abTLS1Master[140] = {
1989 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1990 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1991 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1992 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1993 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1994 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1995 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1996 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1997 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1998 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1999 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2000 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2001 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2002 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2003 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2004 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2005 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2006 0xd3, 0x1e, 0x82, 0xb3
2008 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2009 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2010 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2011 BYTE abClientFinished[16] = "client finished";
2012 BYTE abData[16] = "Wine rocks!";
2014 static const BYTE abEncryptedData[16] = {
2015 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2016 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2018 static const BYTE abPRF[16] = {
2019 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2020 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2022 static const BYTE abMD5[16] = {
2023 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2024 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2027 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2030 win_skip("no PROV_RSA_SCHANNEL support\n");
2033 ok (result, "%08x\n", GetLastError());
2035 CryptReleaseContext(hProv, 0);
2037 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2038 ok (result, "%08x\n", GetLastError());
2039 if (!result) return;
2041 /* To get deterministic results, we import the TLS1 master secret (which
2042 * is typically generated from a random generator). Therefore, we need
2044 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2045 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2046 ok (result, "%08x\n", GetLastError());
2047 if (!result) return;
2049 dwLen = (DWORD)sizeof(abTLS1Master);
2050 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2051 ok (result, "%08x\n", GetLastError());
2052 if (!result) return;
2054 /* Setting the TLS1 client and server random parameters, as well as the
2055 * MAC and encryption algorithm parameters. */
2056 data_blob.cbData = 33;
2057 data_blob.pbData = abClientSecret;
2058 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2059 ok (result, "%08x\n", GetLastError());
2060 if (!result) return;
2062 data_blob.cbData = 33;
2063 data_blob.pbData = abServerSecret;
2064 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2065 ok (result, "%08x\n", GetLastError());
2066 if (!result) return;
2068 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2069 saSChannelAlg.Algid = CALG_DES;
2070 saSChannelAlg.cBits = 64;
2071 saSChannelAlg.dwFlags = 0;
2072 saSChannelAlg.dwReserved = 0;
2073 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2074 ok (result, "%08x\n", GetLastError());
2075 if (!result) return;
2077 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2078 saSChannelAlg.Algid = CALG_MD5;
2079 saSChannelAlg.cBits = 128;
2080 saSChannelAlg.dwFlags = 0;
2081 saSChannelAlg.dwReserved = 0;
2082 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2083 ok (result, "%08x\n", GetLastError());
2084 if (!result) return;
2086 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2087 * (Keys can only be derived from hashes, not from other keys.) */
2088 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2089 ok (result, "%08x\n", GetLastError());
2090 if (!result) return;
2092 /* Deriving the server write encryption key from the master hash */
2093 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2094 ok (result, "%08x\n", GetLastError());
2095 if (!result) return;
2097 /* Encrypting some data with the server write encryption key and checking the result. */
2099 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2100 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2102 /* Second test case: Test the TLS1 pseudo random number function. */
2103 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2104 ok (result, "%08x\n", GetLastError());
2105 if (!result) return;
2107 /* Set the label and seed parameters for the random number function */
2108 data_blob.cbData = 36;
2109 data_blob.pbData = abHashedHandshakes;
2110 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2111 ok (result, "%08x\n", GetLastError());
2112 if (!result) return;
2114 data_blob.cbData = 15;
2115 data_blob.pbData = abClientFinished;
2116 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2117 ok (result, "%08x\n", GetLastError());
2118 if (!result) return;
2120 /* Generate some pseudo random bytes and check if they are correct. */
2121 dwLen = (DWORD)sizeof(abData);
2122 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2123 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2124 "%08x\n", GetLastError());
2126 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2127 * Hash some data with the HMAC. Compare results. */
2128 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2129 ok (result, "%08x\n", GetLastError());
2130 if (!result) return;
2132 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2133 ok (result, "%08x\n", GetLastError());
2134 if (!result) return;
2136 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2137 ok (result, "%08x\n", GetLastError());
2138 if (!result) return;
2140 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2141 ok (result, "%08x\n", GetLastError());
2142 if (!result) return;
2144 dwLen = (DWORD)sizeof(abMD5Hash);
2145 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2146 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2148 CryptDestroyHash(hHMAC);
2149 CryptDestroyHash(hTLS1PRF);
2150 CryptDestroyHash(hMasterHash);
2151 CryptDestroyKey(hServerWriteMACKey);
2152 CryptDestroyKey(hServerWriteKey);
2153 CryptDestroyKey(hRSAKey);
2154 CryptDestroyKey(hMasterSecret);
2155 CryptReleaseContext(hProv, 0);
2156 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2159 /* Test that a key can be used to encrypt data and exported, and that, when
2160 * the exported key is imported again, can be used to decrypt the original
2163 static void test_rsa_round_trip(void)
2165 static const char test_string[] = "Well this is a fine how-do-you-do.";
2167 HCRYPTKEY signKey, keyExchangeKey;
2169 BYTE data[256], *exportedKey;
2170 DWORD dataLen, keyLen;
2172 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2173 CRYPT_DELETEKEYSET);
2175 /* Generate a new key... */
2176 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2178 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2179 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2180 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2181 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2182 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2183 /* encrypt some data with it... */
2184 memcpy(data, test_string, strlen(test_string) + 1);
2185 dataLen = strlen(test_string) + 1;
2186 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2188 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2189 "CryptEncrypt failed: %08x\n", GetLastError());
2190 /* export the key... */
2191 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2193 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2194 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2195 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2197 /* destroy the key... */
2198 CryptDestroyKey(keyExchangeKey);
2199 CryptDestroyKey(signKey);
2200 /* import the key again... */
2201 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2202 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2203 HeapFree(GetProcessHeap(), 0, exportedKey);
2204 /* and decrypt the data encrypted with the original key with the imported
2207 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2208 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2209 "CryptDecrypt failed: %08x\n", GetLastError());
2212 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2213 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2215 CryptDestroyKey(keyExchangeKey);
2216 CryptReleaseContext(prov, 0);
2218 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2219 CRYPT_DELETEKEYSET);
2222 static void test_enum_container(void)
2224 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2226 BOOL result, fFound = FALSE;
2228 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2229 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2230 SetLastError(0xdeadbeef);
2231 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2232 ok (result, "%08x\n", GetLastError());
2233 ok (dwBufferLen == MAX_PATH + 1 ||
2234 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2235 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2237 /* If the result fits into abContainerName dwBufferLen is left untouched */
2238 dwBufferLen = (DWORD)sizeof(abContainerName);
2239 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2240 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2242 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2244 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2245 dwBufferLen = (DWORD)sizeof(abContainerName);
2246 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2248 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2251 static BYTE signBlob[] = {
2252 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2253 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2254 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2255 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2256 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2257 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2258 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2259 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2260 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2261 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2262 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2263 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2264 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2265 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2266 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2267 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2268 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2269 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2270 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2271 0xb6,0x85,0x86,0x07 };
2273 static void test_null_provider(void)
2278 DWORD keySpec, dataLen,dwParam;
2279 char szName[MAX_PATH];
2281 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2282 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2283 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2284 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2285 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2286 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2287 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2288 CRYPT_DELETEKEYSET);
2289 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2290 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2291 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2292 CRYPT_DELETEKEYSET);
2293 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2294 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2295 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2296 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2297 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2299 /* Delete the default container. */
2300 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2301 /* Once you've deleted the default container you can't open it as if it
2304 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2305 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2306 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2307 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2308 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2309 CRYPT_VERIFYCONTEXT);
2310 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2311 if (!result) return;
2312 dataLen = sizeof(keySpec);
2313 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2315 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2316 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2317 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2318 * supported, you can't get the keys from this container.
2320 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2321 ok(!result && GetLastError() == NTE_NO_KEY,
2322 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2323 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2324 ok(!result && GetLastError() == NTE_NO_KEY,
2325 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2326 result = CryptReleaseContext(prov, 0);
2327 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2328 /* You can create a new default container. */
2329 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2331 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2332 /* But you still can't get the keys (until one's been generated.) */
2333 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2334 ok(!result && GetLastError() == NTE_NO_KEY,
2335 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2336 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2337 ok(!result && GetLastError() == NTE_NO_KEY,
2338 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2339 CryptReleaseContext(prov, 0);
2340 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2342 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2343 CRYPT_DELETEKEYSET);
2344 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2345 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2346 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2347 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2348 CRYPT_VERIFYCONTEXT);
2349 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2350 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2351 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2353 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2354 if (!result) return;
2355 /* Test provider parameters getter */
2356 dataLen = sizeof(dwParam);
2357 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2358 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2359 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2360 dataLen = sizeof(dwParam);
2361 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2362 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2363 "Expected 0, got 0x%08X\n",dwParam);
2364 dataLen = sizeof(dwParam);
2365 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2366 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2367 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2368 dataLen = sizeof(keySpec);
2369 SetLastError(0xdeadbeef);
2370 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2371 if (!result && GetLastError() == NTE_BAD_TYPE)
2372 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2374 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2375 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2376 /* PP_CONTAINER parameter */
2377 dataLen = sizeof(szName);
2378 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2379 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2380 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2381 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2382 /* PP_UNIQUE_CONTAINER parameter */
2383 dataLen = sizeof(szName);
2384 SetLastError(0xdeadbeef);
2385 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2386 if (!result && GetLastError() == NTE_BAD_TYPE)
2388 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2392 char container[MAX_PATH];
2394 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2395 uniquecontainer(container);
2398 ok(dataLen == strlen(container)+1 ||
2399 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2400 "Expected a param length of 70, got %d\n", dataLen);
2401 ok(!strcmp(container, szName) ||
2402 broken(!strcmp(szName, szContainer)) /* WinME */,
2403 "Wrong container name : %s\n", szName);
2406 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2407 ok(!result && GetLastError() == NTE_NO_KEY,
2408 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2409 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2410 ok(!result && GetLastError() == NTE_NO_KEY,
2411 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2413 /* Importing a key exchange blob.. */
2414 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2416 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2417 CryptDestroyKey(key);
2418 /* allows access to the key exchange key.. */
2419 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2420 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2421 CryptDestroyKey(key);
2422 /* but not to the private key. */
2423 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2424 ok(!result && GetLastError() == NTE_NO_KEY,
2425 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2426 CryptReleaseContext(prov, 0);
2427 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2428 CRYPT_DELETEKEYSET);
2430 /* Whereas importing a sign blob.. */
2431 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2433 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2434 if (!result) return;
2435 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2436 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2437 CryptDestroyKey(key);
2438 /* doesn't allow access to the key exchange key.. */
2439 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2440 ok(!result && GetLastError() == NTE_NO_KEY,
2441 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2442 /* but does to the private key. */
2443 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2444 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2445 CryptDestroyKey(key);
2446 CryptReleaseContext(prov, 0);
2448 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2449 CRYPT_DELETEKEYSET);
2451 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2452 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2454 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2455 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2456 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2457 CryptDestroyKey(key);
2458 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2459 ok(!result, "expected CryptGetUserKey to fail\n");
2460 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2461 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2462 CryptDestroyKey(key);
2463 CryptReleaseContext(prov, 0);
2465 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2466 CRYPT_DELETEKEYSET);
2468 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2469 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2471 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2472 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2473 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2474 CryptDestroyKey(key);
2475 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2476 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2477 CryptDestroyKey(key);
2478 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2479 ok(!result, "expected CryptGetUserKey to fail\n");
2480 CryptReleaseContext(prov, 0);
2482 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2483 CRYPT_DELETEKEYSET);
2485 /* test for the bug in accessing the user key in a container
2487 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2489 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2490 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2491 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2492 CryptDestroyKey(key);
2493 CryptReleaseContext(prov,0);
2494 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2495 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2496 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2497 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2498 CryptDestroyKey(key);
2499 CryptReleaseContext(prov, 0);
2501 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2502 CRYPT_DELETEKEYSET);
2504 /* test the machine key set */
2505 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2506 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2507 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2508 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2509 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2510 CryptReleaseContext(prov, 0);
2511 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2512 CRYPT_MACHINE_KEYSET);
2513 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2514 CryptReleaseContext(prov,0);
2515 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2516 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2517 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2519 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2520 CRYPT_MACHINE_KEYSET);
2521 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2522 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2526 static void test_key_permissions(void)
2528 HCRYPTKEY hKey1, hKey2;
2532 /* Create keys that are exportable */
2533 if (!init_base_environment(CRYPT_EXPORTABLE))
2536 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2537 ok (result, "%08x\n", GetLastError());
2538 if (!result) return;
2541 dwLen = sizeof(DWORD);
2542 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2543 ok(result, "%08x\n", GetLastError());
2545 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2546 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2547 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2548 " got %08x\n", dwVal);
2550 /* The key exchange key's public key may be exported.. */
2551 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2552 ok(result, "%08x\n", GetLastError());
2553 /* and its private key may be too. */
2554 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2555 ok(result, "%08x\n", GetLastError());
2556 /* Turning off the key's export permissions is "allowed".. */
2557 dwVal &= ~CRYPT_EXPORT;
2558 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2560 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2561 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2562 "%08x\n", GetLastError());
2563 /* but it has no effect. */
2565 dwLen = sizeof(DWORD);
2566 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2567 ok(result, "%08x\n", GetLastError());
2569 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2570 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2571 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2572 " got %08x\n", dwVal);
2573 /* Thus, changing the export flag of the key doesn't affect whether the key
2576 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2577 ok(result, "%08x\n", GetLastError());
2579 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2580 ok (result, "%08x\n", GetLastError());
2582 /* A subsequent get of the same key, into a different handle, also doesn't
2583 * show that the permissions have been changed.
2586 dwLen = sizeof(DWORD);
2587 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2588 ok(result, "%08x\n", GetLastError());
2590 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2591 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2592 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2593 " got %08x\n", dwVal);
2595 CryptDestroyKey(hKey2);
2596 CryptDestroyKey(hKey1);
2598 clean_up_base_environment();
2601 static void test_key_initialization(void)
2604 HCRYPTPROV prov1, prov2;
2605 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2607 static BYTE abSessionKey[148] = {
2608 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2609 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2610 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2611 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2612 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2613 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2614 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2615 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2616 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2617 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2618 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2619 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2620 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2621 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2622 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2623 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2624 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2625 0x04, 0x8c, 0x49, 0x92
2628 /* Like init_base_environment, but doesn't generate new keys, as they'll
2629 * be imported instead.
2631 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2633 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2635 ok(result, "%08x\n", GetLastError());
2637 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2638 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2640 dwLen = (DWORD)sizeof(abSessionKey);
2641 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2642 ok(result, "%08x\n", GetLastError());
2644 /* Once the key has been imported, subsequently acquiring a context with
2645 * the same name will allow retrieving the key.
2647 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2648 ok(result, "%08x\n", GetLastError());
2649 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2650 ok(result, "%08x\n", GetLastError());
2651 if (result) CryptDestroyKey(hKey);
2652 CryptReleaseContext(prov2, 0);
2654 CryptDestroyKey(hSessionKey);
2655 CryptDestroyKey(hKeyExchangeKey);
2656 CryptReleaseContext(prov1, 0);
2657 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2658 CRYPT_DELETEKEYSET);
2663 if (!init_base_environment(0))
2675 test_block_cipher_modes();
2676 test_import_private();
2677 test_verify_signature();
2679 test_import_export();
2680 test_enum_container();
2681 clean_up_base_environment();
2682 test_key_permissions();
2683 test_key_initialization();
2684 test_schannel_provider();
2685 test_null_provider();
2686 test_rsa_round_trip();
2687 if (!init_aes_environment())
2693 clean_up_aes_environment();