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());
496 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
497 ok(result, "%08x\n", GetLastError());
498 ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
501 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
502 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
503 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
505 SetLastError(ERROR_SUCCESS);
507 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
508 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
509 "%08x, dwLen: %d\n", GetLastError(), dwLen);
511 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
512 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
513 "%08x, dwLen: %d\n", GetLastError(), dwLen);
515 dwMode = CRYPT_MODE_CBC;
516 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
517 ok(result, "%08x\n", GetLastError());
520 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
521 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
522 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
525 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
526 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
527 "%08x, dwLen: %d\n", GetLastError(), dwLen);
529 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
530 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
531 "%08x, dwLen: %d\n", GetLastError(), dwLen);
533 dwMode = CRYPT_MODE_CFB;
534 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
535 ok(result, "%08x\n", GetLastError());
538 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
539 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
542 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
543 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
544 "%08x, dwLen: %d\n", GetLastError(), dwLen);
547 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
548 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
551 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
552 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
553 "%08x, dwLen: %d\n", GetLastError(), dwLen);
555 dwMode = CRYPT_MODE_OFB;
556 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
557 ok(result, "%08x\n", GetLastError());
560 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
561 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
563 CryptDestroyKey(hKey);
566 static void test_3des112(void)
571 unsigned char pbData[16];
574 result = derive_key(CALG_3DES_112, &hKey, 0);
576 /* rsaenh compiled without OpenSSL */
577 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
581 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
584 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
585 ok(result, "%08x\n", GetLastError());
587 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
588 ok(result, "%08x\n", GetLastError());
592 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
594 dwLen = cTestData[i].enclen;
595 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
596 ok(result, "%08x\n", GetLastError());
597 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
599 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
600 ok(result, "%08x\n", GetLastError());
601 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
602 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
603 if((dwLen != cTestData[i].enclen) ||
604 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
606 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
607 printBytes("got",pbData,dwLen);
610 result = CryptDestroyKey(hKey);
611 ok(result, "%08x\n", GetLastError());
614 static void test_des(void)
619 unsigned char pbData[16];
622 result = derive_key(CALG_DES, &hKey, 56);
624 /* rsaenh compiled without OpenSSL */
625 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
629 dwMode = CRYPT_MODE_ECB;
630 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
631 ok(result, "%08x\n", GetLastError());
633 dwLen = sizeof(DWORD);
634 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
635 ok(result, "%08x\n", GetLastError());
637 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
640 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
641 ok(result, "%08x\n", GetLastError());
643 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
644 ok(result, "%08x\n", GetLastError());
648 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
650 dwLen = cTestData[i].enclen;
651 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
652 ok(result, "%08x\n", GetLastError());
653 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
655 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
656 ok(result, "%08x\n", GetLastError());
657 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
658 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
659 if((dwLen != cTestData[i].enclen) ||
660 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
662 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
663 printBytes("got",pbData,dwLen);
667 result = CryptDestroyKey(hKey);
668 ok(result, "%08x\n", GetLastError());
671 static void test_3des(void)
676 unsigned char pbData[16];
677 static const BYTE des3[16] = {
678 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
679 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
682 result = derive_key(CALG_3DES, &hKey, 0);
685 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
688 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
689 ok(result, "%08x\n", GetLastError());
691 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
693 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
694 ok(result, "%08x\n", GetLastError());
698 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
700 dwLen = cTestData[i].enclen;
701 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
702 ok(result, "%08x\n", GetLastError());
703 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
705 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
706 ok(result, "%08x\n", GetLastError());
707 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
708 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
709 if((dwLen != cTestData[i].enclen) ||
710 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
712 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
713 printBytes("got",pbData,dwLen);
716 result = CryptDestroyKey(hKey);
717 ok(result, "%08x\n", GetLastError());
720 static void test_aes(int keylen)
725 unsigned char pbData[16];
731 result = derive_key(CALG_AES_256, &hKey, 0);
734 result = derive_key(CALG_AES_192, &hKey, 0);
738 result = derive_key(CALG_AES_128, &hKey, 0);
743 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
745 /* AES provider doesn't support salt */
746 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
748 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == ERROR_NO_TOKEN /* Win7 */),
749 "expected NTE_BAD_KEY or ERROR_NO_TOKEN, got %08x\n", GetLastError());
752 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
753 ok(result, "%08x\n", GetLastError());
755 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
756 ok(result, "%08x\n", GetLastError());
760 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
762 dwLen = cTestData[i].enclen;
763 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
764 ok(result, "%08x\n", GetLastError());
765 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
767 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
768 ok(result, "%08x\n", GetLastError());
769 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
770 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
771 if((dwLen != cTestData[i].enclen) ||
772 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
774 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
775 printBytes("got",pbData,dwLen);
778 result = CryptDestroyKey(hKey);
779 ok(result, "%08x\n", GetLastError());
782 static void test_sha2(void)
784 static const unsigned char sha256hash[32] = {
785 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
786 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
787 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
790 static const unsigned char sha384hash[48] = {
791 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
792 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
793 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
794 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
795 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
797 static const unsigned char sha512hash[64] = {
798 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
799 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
800 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
801 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
802 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
803 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
804 0xb7, 0xf4, 0x81, 0xd4
806 unsigned char pbData[2048];
809 BYTE pbHashValue[64];
813 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
816 SetLastError(0xdeadbeef);
817 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
818 if (!result && GetLastError() == NTE_BAD_ALGID) {
819 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
822 ok(result, "%08x\n", GetLastError());
825 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
826 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
828 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
829 ok(result, "%08x\n", GetLastError());
832 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
833 ok(result, "%08x\n", GetLastError());
835 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
837 result = CryptDestroyHash(hHash);
838 ok(result, "%08x\n", GetLastError());
842 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
843 ok(result, "%08x\n", GetLastError());
846 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
847 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
849 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
850 ok(result, "%08x\n", GetLastError());
853 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
854 ok(result, "%08x\n", GetLastError());
856 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
858 result = CryptDestroyHash(hHash);
859 ok(result, "%08x\n", GetLastError());
863 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
864 ok(result, "%08x\n", GetLastError());
867 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
868 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
870 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
871 ok(result, "%08x\n", GetLastError());
874 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
875 ok(result, "%08x\n", GetLastError());
877 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
879 result = CryptDestroyHash(hHash);
880 ok(result, "%08x\n", GetLastError());
884 static void test_rc2(void)
886 static const BYTE rc2_40_encrypted[16] = {
887 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
888 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
889 static const BYTE rc2_128_encrypted[] = {
890 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
895 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
897 unsigned char pbData[2000], pbHashValue[16];
900 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
903 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
905 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
907 CRYPT_INTEGER_BLOB salt;
909 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
910 ok(result, "%08x\n", GetLastError());
913 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
914 ok(result, "%08x\n", GetLastError());
916 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
917 ok(result, "%08x\n", GetLastError());
919 dwLen = sizeof(DWORD);
920 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
921 ok(result, "%08x\n", GetLastError());
923 dwMode = CRYPT_MODE_CBC;
924 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
925 ok(result, "%08x\n", GetLastError());
927 dwLen = sizeof(DWORD);
928 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
929 ok(result, "%08x\n", GetLastError());
931 dwModeBits = 0xdeadbeef;
932 dwLen = sizeof(DWORD);
933 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
934 ok(result, "%08x\n", GetLastError());
936 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
937 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
938 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
939 " got %08x\n", dwModeBits);
941 dwLen = sizeof(DWORD);
942 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
943 ok(result, "%08x\n", GetLastError());
945 dwLen = sizeof(DWORD);
946 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
947 ok(result, "%08x\n", GetLastError());
949 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
950 ok(result, "%08x\n", GetLastError());
951 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
952 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
953 HeapFree(GetProcessHeap(), 0, pbTemp);
955 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
956 ok(result, "%08x\n", GetLastError());
957 /* The default salt length is always 11... */
958 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
959 /* and the default salt is always empty. */
960 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
961 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
962 for (i=0; i<dwLen; i++)
963 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
964 HeapFree(GetProcessHeap(), 0, pbTemp);
966 dwLen = sizeof(DWORD);
967 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
969 result = CryptDestroyHash(hHash);
970 ok(result, "%08x\n", GetLastError());
973 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
974 ok(result, "%08x\n", GetLastError());
976 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
978 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
979 ok(result, "%08x\n", GetLastError());
980 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
981 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
982 HeapFree(GetProcessHeap(), 0, pbTemp);
984 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
985 ok(result, "%08x\n", GetLastError());
987 /* Setting the salt also succeeds... */
988 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
990 ok(result, "setting salt failed: %08x\n", GetLastError());
991 /* but the resulting salt length is now zero? */
993 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
994 ok(result, "%08x\n", GetLastError());
996 ok(dwLen == 0, "unexpected salt length %d\n", dwLen);
997 /* What sizes salt can I set? */
998 salt.pbData = pbData;
1002 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1003 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1004 /* The returned salt length is the same as the set salt length */
1005 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1006 ok(result, "%08x\n", GetLastError());
1007 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1010 SetLastError(0xdeadbeef);
1011 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1013 broken(result), /* Win9x, WinMe, NT4, W2K */
1014 "%08x\n", GetLastError());
1016 result = CryptDestroyKey(hKey);
1017 ok(result, "%08x\n", GetLastError());
1020 /* Again, but test setting the effective key len */
1021 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1023 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1025 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1027 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1028 ok(result, "%08x\n", GetLastError());
1031 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1032 ok(result, "%08x\n", GetLastError());
1034 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1035 ok(result, "%08x\n", GetLastError());
1037 SetLastError(0xdeadbeef);
1038 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1039 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1041 SetLastError(0xdeadbeef);
1042 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1043 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1045 SetLastError(0xdeadbeef);
1046 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1048 dwLen = sizeof(dwKeyLen);
1049 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1050 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1051 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1052 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1055 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1056 ok(result, "%d\n", GetLastError());
1058 dwLen = sizeof(dwKeyLen);
1059 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1060 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1061 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1062 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1064 result = CryptDestroyHash(hHash);
1065 ok(result, "%08x\n", GetLastError());
1068 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1069 ok(result, "%08x\n", GetLastError());
1071 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1072 "RC2 encryption failed!\n");
1074 /* Oddly enough this succeeds, though it should have no effect */
1076 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1077 ok(result, "%d\n", GetLastError());
1079 result = CryptDestroyKey(hKey);
1080 ok(result, "%08x\n", GetLastError());
1084 static void test_rc4(void)
1086 static const BYTE rc4[16] = {
1087 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1088 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1092 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1093 unsigned char pbData[2000], *pbTemp;
1094 unsigned char pszBuffer[256];
1097 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1100 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1102 /* rsaenh compiled without OpenSSL */
1103 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1105 CRYPT_INTEGER_BLOB salt;
1107 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1108 ok(result, "%08x\n", GetLastError());
1111 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1112 ok(result, "%08x\n", GetLastError());
1114 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1115 ok(result, "%08x\n", GetLastError());
1117 dwLen = sizeof(DWORD);
1118 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1119 ok(result, "%08x\n", GetLastError());
1121 dwLen = sizeof(DWORD);
1122 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1123 ok(result, "%08x\n", GetLastError());
1125 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1126 ok(result, "%08x\n", GetLastError());
1127 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1128 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1129 HeapFree(GetProcessHeap(), 0, pbTemp);
1131 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1132 ok(result, "%08x\n", GetLastError());
1133 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1134 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1135 HeapFree(GetProcessHeap(), 0, pbTemp);
1137 dwLen = sizeof(DWORD);
1138 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1140 result = CryptDestroyHash(hHash);
1141 ok(result, "%08x\n", GetLastError());
1144 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1145 ok(result, "%08x\n", GetLastError());
1147 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1148 ok(result, "%08x\n", GetLastError());
1150 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1152 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1153 ok(result, "%08x\n", GetLastError());
1155 /* Setting the salt also succeeds... */
1156 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1158 ok(result, "setting salt failed: %08x\n", GetLastError());
1159 /* but the resulting salt length is now zero? */
1161 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1162 ok(result, "%08x\n", GetLastError());
1163 ok(dwLen == 0, "unexpected salt length %d\n", dwLen);
1164 /* What sizes salt can I set? */
1165 salt.pbData = pbData;
1166 for (i=0; i<24; i++)
1169 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1170 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1171 /* The returned salt length is the same as the set salt length */
1172 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1173 ok(result, "%08x\n", GetLastError());
1174 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1177 SetLastError(0xdeadbeef);
1178 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1180 broken(result), /* Win9x, WinMe, NT4, W2K */
1181 "%08x\n", GetLastError());
1183 result = CryptDestroyKey(hKey);
1184 ok(result, "%08x\n", GetLastError());
1188 static void test_hmac(void) {
1192 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1193 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1196 static const BYTE hmac[16] = {
1197 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1198 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1201 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1203 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1205 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1206 ok(result, "%08x\n", GetLastError());
1207 if (!result) return;
1209 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1210 ok(result, "%08x\n", GetLastError());
1212 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1213 ok(result, "%08x\n", GetLastError());
1215 dwLen = sizeof(abData)/sizeof(BYTE);
1216 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1217 ok(result, "%08x\n", GetLastError());
1219 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1221 result = CryptDestroyHash(hHash);
1222 ok(result, "%08x\n", GetLastError());
1224 result = CryptDestroyKey(hKey);
1225 ok(result, "%08x\n", GetLastError());
1227 /* Provoke errors */
1228 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1229 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1232 static void test_mac(void) {
1237 BYTE abData[256], abEnc[264];
1238 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1241 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1242 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1244 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1247 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1248 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1250 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1251 ok(result, "%08x\n", GetLastError());
1252 if (!result) return;
1254 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1255 ok(result, "%08x\n", GetLastError());
1257 dwLen = sizeof(abData)/sizeof(BYTE);
1258 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1259 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1261 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1263 result = CryptDestroyHash(hHash);
1264 ok(result, "%08x\n", GetLastError());
1266 result = CryptDestroyKey(hKey);
1267 ok(result, "%08x\n", GetLastError());
1269 /* Provoke errors */
1270 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1272 SetLastError(0xdeadbeef);
1273 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1274 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1275 broken(result), /* Win9x, WinMe, NT4, W2K */
1276 "%08x\n", GetLastError());
1278 result = CryptDestroyKey(hKey);
1279 ok(result, "%08x\n", GetLastError());
1282 static BYTE abPlainPrivateKey[596] = {
1283 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1284 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1285 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1286 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1287 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1288 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1289 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1290 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1291 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1292 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1293 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1294 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1295 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1296 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1297 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1298 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1299 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1300 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1301 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1302 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1303 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1304 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1305 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1306 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1307 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1308 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1309 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1310 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1311 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1312 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1313 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1314 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1315 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1316 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1317 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1318 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1319 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1320 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1321 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1322 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1323 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1324 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1325 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1326 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1327 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1328 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1329 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1330 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1331 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1332 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1333 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1334 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1335 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1336 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1337 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1338 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1339 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1340 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1341 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1342 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1343 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1344 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1345 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1346 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1347 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1348 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1349 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1350 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1351 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1352 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1353 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1354 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1355 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1356 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1357 0xf2, 0x5d, 0x58, 0x07
1360 static void test_import_private(void)
1363 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1365 static BYTE abSessionKey[148] = {
1366 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1367 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1368 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1369 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1370 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1371 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1372 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1373 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1374 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1375 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1376 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1377 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1378 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1379 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1380 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1381 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1382 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1383 0x04, 0x8c, 0x49, 0x92
1385 static BYTE abEncryptedMessage[12] = {
1386 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1387 0x1c, 0xfd, 0xde, 0x71
1390 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1391 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1393 /* rsaenh compiled without OpenSSL */
1394 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1398 dwLen = (DWORD)sizeof(abSessionKey);
1399 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1400 ok(result, "%08x\n", GetLastError());
1401 if (!result) return;
1404 dwLen = sizeof(DWORD);
1405 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1406 ok(result, "%08x\n", GetLastError());
1408 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1409 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1410 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1411 " got %08x\n", dwVal);
1413 dwLen = (DWORD)sizeof(abEncryptedMessage);
1414 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1415 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1416 "%08x, len: %d\n", GetLastError(), dwLen);
1417 CryptDestroyKey(hSessionKey);
1419 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1421 dwLen = (DWORD)sizeof(abSessionKey);
1422 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1423 ok(result, "%08x\n", GetLastError());
1424 CryptDestroyKey(hSessionKey);
1425 if (!result) return;
1427 dwLen = (DWORD)sizeof(abSessionKey);
1428 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1429 ok(result, "%08x\n", GetLastError());
1430 if (!result) return;
1432 CryptDestroyKey(hSessionKey);
1433 CryptDestroyKey(hKeyExchangeKey);
1436 static void test_verify_signature(void) {
1438 HCRYPTKEY hPubSignKey;
1439 BYTE abData[] = "Wine rocks!";
1441 BYTE abPubKey[148] = {
1442 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1443 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1444 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1445 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1446 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1447 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1448 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1449 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1450 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1451 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1452 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1453 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1454 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1455 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1456 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1457 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1458 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1459 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1460 0xe1, 0x21, 0x50, 0xac
1462 /* md2 with hash oid */
1463 BYTE abSignatureMD2[128] = {
1464 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1465 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1466 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1467 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1468 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1469 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1470 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1471 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1472 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1473 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1474 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1475 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1476 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1477 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1478 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1479 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1481 /* md2 without hash oid */
1482 BYTE abSignatureMD2NoOID[128] = {
1483 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1484 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1485 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1486 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1487 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1488 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1489 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1490 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1491 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1492 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1493 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1494 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1495 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1496 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1497 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1498 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1500 /* md4 with hash oid */
1501 BYTE abSignatureMD4[128] = {
1502 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1503 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1504 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1505 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1506 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1507 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1508 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1509 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1510 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1511 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1512 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1513 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1514 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1515 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1516 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1517 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1519 /* md4 without hash oid */
1520 BYTE abSignatureMD4NoOID[128] = {
1521 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1522 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1523 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1524 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1525 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1526 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1527 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1528 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1529 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1530 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1531 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1532 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1533 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1534 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1535 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1536 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1538 /* md5 with hash oid */
1539 BYTE abSignatureMD5[128] = {
1540 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1541 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1542 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1543 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1544 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1545 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1546 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1547 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1548 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1549 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1550 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1551 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1552 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1553 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1554 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1555 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1557 /* md5 without hash oid */
1558 BYTE abSignatureMD5NoOID[128] = {
1559 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1560 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1561 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1562 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1563 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1564 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1565 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1566 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1567 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1568 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1569 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1570 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1571 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1572 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1573 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1574 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1576 /* sha with hash oid */
1577 BYTE abSignatureSHA[128] = {
1578 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1579 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1580 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1581 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1582 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1583 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1584 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1585 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1586 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1587 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1588 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1589 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1590 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1591 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1592 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1593 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1595 /* sha without hash oid */
1596 BYTE abSignatureSHANoOID[128] = {
1597 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1598 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1599 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1600 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1601 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1602 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1603 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1604 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1605 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1606 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1607 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1608 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1609 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1610 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1611 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1612 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1615 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1616 ok(result, "%08x\n", GetLastError());
1617 if (!result) return;
1619 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1620 ok(result, "%08x\n", GetLastError());
1621 if (!result) return;
1623 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1624 ok(result, "%08x\n", GetLastError());
1625 if (!result) return;
1627 /*check that a NULL pointer signature is correctly handled*/
1628 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1629 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1630 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1633 /* check that we get a bad signature error when the signature is too short*/
1634 SetLastError(0xdeadbeef);
1635 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1636 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1637 broken(result), /* Win9x, WinMe, NT4 */
1638 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1640 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1641 ok(result, "%08x\n", GetLastError());
1642 if (!result) return;
1644 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1645 ok(result, "%08x\n", GetLastError());
1646 if (!result) return;
1648 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1649 * the OID at all. */
1650 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1651 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1652 if (result) return;*/
1654 CryptDestroyHash(hHash);
1656 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1657 ok(result, "%08x\n", GetLastError());
1658 if (!result) return;
1660 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1661 ok(result, "%08x\n", GetLastError());
1662 if (!result) return;
1664 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1665 ok(result, "%08x\n", GetLastError());
1666 if (!result) return;
1668 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1669 ok(result, "%08x\n", GetLastError());
1670 if (!result) return;
1672 CryptDestroyHash(hHash);
1674 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1675 ok(result, "%08x\n", GetLastError());
1676 if (!result) return;
1678 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1679 ok(result, "%08x\n", GetLastError());
1680 if (!result) return;
1682 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1683 ok(result, "%08x\n", GetLastError());
1684 if (!result) return;
1686 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1687 ok(result, "%08x\n", GetLastError());
1688 if (!result) return;
1690 CryptDestroyHash(hHash);
1692 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1693 ok(result, "%08x\n", GetLastError());
1694 if (!result) return;
1696 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1697 ok(result, "%08x\n", GetLastError());
1698 if (!result) return;
1700 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1701 ok(result, "%08x\n", GetLastError());
1702 if (!result) return;
1704 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1705 ok(result, "%08x\n", GetLastError());
1706 if (!result) return;
1708 CryptDestroyHash(hHash);
1709 CryptDestroyKey(hPubSignKey);
1712 static void test_rsa_encrypt(void)
1715 BYTE abData[2048] = "Wine rocks!";
1719 /* It is allowed to use the key exchange key for encryption/decryption */
1720 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1721 ok (result, "%08x\n", GetLastError());
1722 if (!result) return;
1725 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1726 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1727 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1729 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1730 ok (result, "%08x\n", GetLastError());
1731 if (!result) return;
1733 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1734 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1737 dwLen = sizeof(DWORD);
1738 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1739 ok(result, "%08x\n", GetLastError());
1741 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1742 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1743 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1744 " got %08x\n", dwVal);
1746 /* An RSA key doesn't support salt */
1747 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1749 ok(!result && GetLastError() == NTE_BAD_KEY,
1750 "expected NTE_BAD_KEY, got %08x\n", GetLastError());
1752 /* The key exchange key's public key may be exported.. */
1753 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1754 ok(result, "%08x\n", GetLastError());
1755 /* but its private key may not be. */
1756 SetLastError(0xdeadbeef);
1757 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1758 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1759 broken(result), /* Win9x/NT4 */
1760 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1761 /* Setting the permissions of the key exchange key isn't allowed, either. */
1762 dwVal |= CRYPT_EXPORT;
1763 SetLastError(0xdeadbeef);
1764 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1766 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1767 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1769 CryptDestroyKey(hRSAKey);
1771 /* It is not allowed to use the signature key for encryption/decryption */
1772 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1773 ok (result, "%08x\n", GetLastError());
1774 if (!result) return;
1777 dwLen = sizeof(DWORD);
1778 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1779 ok(result, "%08x\n", GetLastError());
1781 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1782 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1783 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1784 " got %08x\n", dwVal);
1786 /* The signature key's public key may also be exported.. */
1787 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1788 ok(result, "%08x\n", GetLastError());
1789 /* but its private key may not be. */
1790 SetLastError(0xdeadbeef);
1791 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1792 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1793 broken(result), /* Win9x/NT4 */
1794 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1795 /* Setting the permissions of the signature key isn't allowed, either. */
1796 dwVal |= CRYPT_EXPORT;
1797 SetLastError(0xdeadbeef);
1798 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1800 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1801 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1804 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1805 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1807 CryptDestroyKey(hRSAKey);
1810 static void test_import_export(void)
1812 DWORD dwLen, dwDataLen, dwVal;
1813 HCRYPTKEY hPublicKey, hPrivKey;
1816 BYTE emptyKey[2048], *exported_key;
1817 static BYTE abPlainPublicKey[84] = {
1818 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1819 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1820 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1821 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1822 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1823 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1824 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1825 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1826 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1827 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1828 0x11, 0x11, 0x11, 0x11
1830 static BYTE priv_key_with_high_bit[] = {
1831 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1832 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1833 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1834 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1835 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1836 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1837 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1838 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1839 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1840 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1841 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1842 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1843 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1844 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1845 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1846 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1847 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1848 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1849 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1850 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1851 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1852 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1853 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1854 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1855 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1856 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1857 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1858 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1859 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1860 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1861 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1862 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1863 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1864 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1865 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1866 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1867 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1868 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1869 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1870 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1871 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1872 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1873 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1874 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1875 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1876 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1877 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1878 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1879 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1880 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1881 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1882 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1883 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1884 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1885 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1886 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1887 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1888 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1889 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1890 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1891 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1892 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1893 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1894 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1895 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1896 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1897 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1898 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1899 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1900 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1901 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1902 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1903 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1904 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1905 0xb6, 0x5f, 0x01, 0x5e
1907 static const BYTE expected_exported_priv_key[] = {
1908 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1909 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1910 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1911 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1912 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1913 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1914 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1915 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1916 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1917 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1918 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1919 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1920 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1921 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1922 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1923 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1924 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1925 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1926 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1927 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1928 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1929 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1930 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1931 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1932 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1933 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1934 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1935 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1936 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1937 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1938 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1939 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1940 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1941 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1942 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1943 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1944 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1945 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1946 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1947 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1948 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1949 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1950 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1951 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1952 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1953 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1954 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1955 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1956 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1957 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1958 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1959 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1960 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1961 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1962 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1963 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1964 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1965 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1966 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1967 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1968 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1969 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1970 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1971 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1972 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1973 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1974 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1975 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1976 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1977 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1978 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1979 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1980 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1981 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1982 0xb6, 0x5f, 0x01, 0x5e
1986 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1987 ok(result, "failed to import the public key\n");
1989 dwDataLen=sizeof(algID);
1990 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1991 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1992 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1995 dwDataLen = sizeof(DWORD);
1996 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
1997 ok(result, "%08x\n", GetLastError());
1999 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2000 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2001 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2002 " got %08x\n", dwVal);
2003 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2004 ok(result, "failed to export the fresh imported public key\n");
2005 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2006 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2008 CryptDestroyKey(hPublicKey);
2010 result = CryptImportKey(hProv, priv_key_with_high_bit,
2011 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2012 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2014 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2015 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2016 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2017 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2019 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2021 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2023 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2024 "unexpected value\n");
2026 HeapFree(GetProcessHeap(), 0, exported_key);
2028 CryptDestroyKey(hPrivKey);
2031 static void test_schannel_provider(void)
2034 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2035 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2038 SCHANNEL_ALG saSChannelAlg;
2039 CRYPT_DATA_BLOB data_blob;
2040 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2041 BYTE abTLS1Master[140] = {
2042 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2043 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2044 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2045 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2046 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2047 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2048 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2049 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2050 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2051 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2052 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2053 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2054 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2055 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2056 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2057 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2058 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2059 0xd3, 0x1e, 0x82, 0xb3
2061 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2062 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2063 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2064 BYTE abClientFinished[16] = "client finished";
2065 BYTE abData[16] = "Wine rocks!";
2067 static const BYTE abEncryptedData[16] = {
2068 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2069 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2071 static const BYTE abPRF[16] = {
2072 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2073 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2075 static const BYTE abMD5[16] = {
2076 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2077 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2080 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2083 win_skip("no PROV_RSA_SCHANNEL support\n");
2086 ok (result, "%08x\n", GetLastError());
2088 CryptReleaseContext(hProv, 0);
2090 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2091 ok (result, "%08x\n", GetLastError());
2092 if (!result) return;
2094 /* To get deterministic results, we import the TLS1 master secret (which
2095 * is typically generated from a random generator). Therefore, we need
2097 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2098 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2099 ok (result, "%08x\n", GetLastError());
2100 if (!result) return;
2102 dwLen = (DWORD)sizeof(abTLS1Master);
2103 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2104 ok (result, "%08x\n", GetLastError());
2105 if (!result) return;
2107 /* Setting the TLS1 client and server random parameters, as well as the
2108 * MAC and encryption algorithm parameters. */
2109 data_blob.cbData = 33;
2110 data_blob.pbData = abClientSecret;
2111 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2112 ok (result, "%08x\n", GetLastError());
2113 if (!result) return;
2115 data_blob.cbData = 33;
2116 data_blob.pbData = abServerSecret;
2117 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2118 ok (result, "%08x\n", GetLastError());
2119 if (!result) return;
2121 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2122 saSChannelAlg.Algid = CALG_DES;
2123 saSChannelAlg.cBits = 64;
2124 saSChannelAlg.dwFlags = 0;
2125 saSChannelAlg.dwReserved = 0;
2126 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2127 ok (result, "%08x\n", GetLastError());
2128 if (!result) return;
2130 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2131 saSChannelAlg.Algid = CALG_MD5;
2132 saSChannelAlg.cBits = 128;
2133 saSChannelAlg.dwFlags = 0;
2134 saSChannelAlg.dwReserved = 0;
2135 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2136 ok (result, "%08x\n", GetLastError());
2137 if (!result) return;
2139 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2140 * (Keys can only be derived from hashes, not from other keys.) */
2141 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2142 ok (result, "%08x\n", GetLastError());
2143 if (!result) return;
2145 /* Deriving the server write encryption key from the master hash */
2146 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2147 ok (result, "%08x\n", GetLastError());
2148 if (!result) return;
2150 /* Encrypting some data with the server write encryption key and checking the result. */
2152 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2153 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2155 /* Second test case: Test the TLS1 pseudo random number function. */
2156 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2157 ok (result, "%08x\n", GetLastError());
2158 if (!result) return;
2160 /* Set the label and seed parameters for the random number function */
2161 data_blob.cbData = 36;
2162 data_blob.pbData = abHashedHandshakes;
2163 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2164 ok (result, "%08x\n", GetLastError());
2165 if (!result) return;
2167 data_blob.cbData = 15;
2168 data_blob.pbData = abClientFinished;
2169 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2170 ok (result, "%08x\n", GetLastError());
2171 if (!result) return;
2173 /* Generate some pseudo random bytes and check if they are correct. */
2174 dwLen = (DWORD)sizeof(abData);
2175 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2176 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2177 "%08x\n", GetLastError());
2179 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2180 * Hash some data with the HMAC. Compare results. */
2181 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2182 ok (result, "%08x\n", GetLastError());
2183 if (!result) return;
2185 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2186 ok (result, "%08x\n", GetLastError());
2187 if (!result) return;
2189 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2190 ok (result, "%08x\n", GetLastError());
2191 if (!result) return;
2193 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2194 ok (result, "%08x\n", GetLastError());
2195 if (!result) return;
2197 dwLen = (DWORD)sizeof(abMD5Hash);
2198 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2199 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2201 CryptDestroyHash(hHMAC);
2202 CryptDestroyHash(hTLS1PRF);
2203 CryptDestroyHash(hMasterHash);
2204 CryptDestroyKey(hServerWriteMACKey);
2205 CryptDestroyKey(hServerWriteKey);
2206 CryptDestroyKey(hRSAKey);
2207 CryptDestroyKey(hMasterSecret);
2208 CryptReleaseContext(hProv, 0);
2209 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2212 /* Test that a key can be used to encrypt data and exported, and that, when
2213 * the exported key is imported again, can be used to decrypt the original
2216 static void test_rsa_round_trip(void)
2218 static const char test_string[] = "Well this is a fine how-do-you-do.";
2220 HCRYPTKEY signKey, keyExchangeKey;
2222 BYTE data[256], *exportedKey;
2223 DWORD dataLen, keyLen;
2225 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2226 CRYPT_DELETEKEYSET);
2228 /* Generate a new key... */
2229 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2231 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2232 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2233 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2234 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2235 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2236 /* encrypt some data with it... */
2237 memcpy(data, test_string, strlen(test_string) + 1);
2238 dataLen = strlen(test_string) + 1;
2239 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2241 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2242 "CryptEncrypt failed: %08x\n", GetLastError());
2243 /* export the key... */
2244 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2246 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2247 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2248 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2250 /* destroy the key... */
2251 CryptDestroyKey(keyExchangeKey);
2252 CryptDestroyKey(signKey);
2253 /* import the key again... */
2254 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2255 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2256 HeapFree(GetProcessHeap(), 0, exportedKey);
2257 /* and decrypt the data encrypted with the original key with the imported
2260 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2261 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2262 "CryptDecrypt failed: %08x\n", GetLastError());
2265 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2266 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2268 CryptDestroyKey(keyExchangeKey);
2269 CryptReleaseContext(prov, 0);
2271 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2272 CRYPT_DELETEKEYSET);
2275 static void test_enum_container(void)
2277 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2279 BOOL result, fFound = FALSE;
2281 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2282 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2283 SetLastError(0xdeadbeef);
2284 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2285 ok (result, "%08x\n", GetLastError());
2286 ok (dwBufferLen == MAX_PATH + 1 ||
2287 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2288 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2290 /* If the result fits into abContainerName dwBufferLen is left untouched */
2291 dwBufferLen = (DWORD)sizeof(abContainerName);
2292 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2293 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2295 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2297 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2298 dwBufferLen = (DWORD)sizeof(abContainerName);
2299 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2301 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2304 static BYTE signBlob[] = {
2305 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2306 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2307 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2308 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2309 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2310 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2311 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2312 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2313 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2314 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2315 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2316 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2317 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2318 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2319 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2320 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2321 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2322 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2323 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2324 0xb6,0x85,0x86,0x07 };
2326 static void test_null_provider(void)
2331 DWORD keySpec, dataLen,dwParam;
2332 char szName[MAX_PATH];
2334 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2335 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2336 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2337 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2338 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2339 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2340 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2341 CRYPT_DELETEKEYSET);
2342 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2343 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2344 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2345 CRYPT_DELETEKEYSET);
2346 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2347 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2348 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2349 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2350 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2352 /* Delete the default container. */
2353 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2354 /* Once you've deleted the default container you can't open it as if it
2357 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2358 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2359 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2360 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2361 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2362 CRYPT_VERIFYCONTEXT);
2363 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2364 if (!result) return;
2365 dataLen = sizeof(keySpec);
2366 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2368 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2369 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2370 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2371 * supported, you can't get the keys from this container.
2373 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2374 ok(!result && GetLastError() == NTE_NO_KEY,
2375 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2376 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2377 ok(!result && GetLastError() == NTE_NO_KEY,
2378 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2379 result = CryptReleaseContext(prov, 0);
2380 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2381 /* You can create a new default container. */
2382 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2384 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2385 /* But you still can't get the keys (until one's been generated.) */
2386 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2387 ok(!result && GetLastError() == NTE_NO_KEY,
2388 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2389 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2390 ok(!result && GetLastError() == NTE_NO_KEY,
2391 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2392 CryptReleaseContext(prov, 0);
2393 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2395 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2396 CRYPT_DELETEKEYSET);
2397 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2398 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2399 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2400 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2401 CRYPT_VERIFYCONTEXT);
2402 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2403 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2404 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2406 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2407 if (!result) return;
2408 /* Test provider parameters getter */
2409 dataLen = sizeof(dwParam);
2410 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2411 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2412 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2413 dataLen = sizeof(dwParam);
2414 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2415 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2416 "Expected 0, got 0x%08X\n",dwParam);
2417 dataLen = sizeof(dwParam);
2418 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2419 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2420 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2421 dataLen = sizeof(keySpec);
2422 SetLastError(0xdeadbeef);
2423 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2424 if (!result && GetLastError() == NTE_BAD_TYPE)
2425 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2427 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2428 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2429 /* PP_CONTAINER parameter */
2430 dataLen = sizeof(szName);
2431 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2432 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2433 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2434 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2435 /* PP_UNIQUE_CONTAINER parameter */
2436 dataLen = sizeof(szName);
2437 SetLastError(0xdeadbeef);
2438 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2439 if (!result && GetLastError() == NTE_BAD_TYPE)
2441 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2445 char container[MAX_PATH];
2447 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2448 uniquecontainer(container);
2451 ok(dataLen == strlen(container)+1 ||
2452 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2453 "Expected a param length of 70, got %d\n", dataLen);
2454 ok(!strcmp(container, szName) ||
2455 broken(!strcmp(szName, szContainer)) /* WinME */,
2456 "Wrong container name : %s\n", szName);
2459 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2460 ok(!result && GetLastError() == NTE_NO_KEY,
2461 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2462 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2463 ok(!result && GetLastError() == NTE_NO_KEY,
2464 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2466 /* Importing a key exchange blob.. */
2467 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2469 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2470 CryptDestroyKey(key);
2471 /* allows access to the key exchange key.. */
2472 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2473 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2474 CryptDestroyKey(key);
2475 /* but not to the private key. */
2476 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2477 ok(!result && GetLastError() == NTE_NO_KEY,
2478 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2479 CryptReleaseContext(prov, 0);
2480 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2481 CRYPT_DELETEKEYSET);
2483 /* Whereas importing a sign blob.. */
2484 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2486 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2487 if (!result) return;
2488 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2489 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2490 CryptDestroyKey(key);
2491 /* doesn't allow access to the key exchange key.. */
2492 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2493 ok(!result && GetLastError() == NTE_NO_KEY,
2494 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2495 /* but does to the private key. */
2496 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2497 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2498 CryptDestroyKey(key);
2499 CryptReleaseContext(prov, 0);
2501 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2502 CRYPT_DELETEKEYSET);
2504 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2505 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2507 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2508 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2509 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2510 CryptDestroyKey(key);
2511 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2512 ok(!result, "expected CryptGetUserKey to fail\n");
2513 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2514 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2515 CryptDestroyKey(key);
2516 CryptReleaseContext(prov, 0);
2518 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2519 CRYPT_DELETEKEYSET);
2521 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2522 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2524 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2525 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2526 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2527 CryptDestroyKey(key);
2528 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2529 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2530 CryptDestroyKey(key);
2531 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2532 ok(!result, "expected CryptGetUserKey to fail\n");
2533 CryptReleaseContext(prov, 0);
2535 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2536 CRYPT_DELETEKEYSET);
2538 /* test for the bug in accessing the user key in a container
2540 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2542 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2543 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2544 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2545 CryptDestroyKey(key);
2546 CryptReleaseContext(prov,0);
2547 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2548 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2549 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2550 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2551 CryptDestroyKey(key);
2552 CryptReleaseContext(prov, 0);
2554 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2555 CRYPT_DELETEKEYSET);
2557 /* test the machine key set */
2558 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2559 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2560 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2561 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2562 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2563 CryptReleaseContext(prov, 0);
2564 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2565 CRYPT_MACHINE_KEYSET);
2566 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2567 CryptReleaseContext(prov,0);
2568 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2569 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2570 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2572 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2573 CRYPT_MACHINE_KEYSET);
2574 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2575 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2579 static void test_key_permissions(void)
2581 HCRYPTKEY hKey1, hKey2;
2585 /* Create keys that are exportable */
2586 if (!init_base_environment(CRYPT_EXPORTABLE))
2589 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2590 ok (result, "%08x\n", GetLastError());
2591 if (!result) return;
2594 dwLen = sizeof(DWORD);
2595 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2596 ok(result, "%08x\n", GetLastError());
2598 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2599 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2600 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2601 " got %08x\n", dwVal);
2603 /* The key exchange key's public key may be exported.. */
2604 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2605 ok(result, "%08x\n", GetLastError());
2606 /* and its private key may be too. */
2607 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2608 ok(result, "%08x\n", GetLastError());
2609 /* Turning off the key's export permissions is "allowed".. */
2610 dwVal &= ~CRYPT_EXPORT;
2611 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2613 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2614 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2615 "%08x\n", GetLastError());
2616 /* but it has no effect. */
2618 dwLen = sizeof(DWORD);
2619 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2620 ok(result, "%08x\n", GetLastError());
2622 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2623 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2624 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2625 " got %08x\n", dwVal);
2626 /* Thus, changing the export flag of the key doesn't affect whether the key
2629 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2630 ok(result, "%08x\n", GetLastError());
2632 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2633 ok (result, "%08x\n", GetLastError());
2635 /* A subsequent get of the same key, into a different handle, also doesn't
2636 * show that the permissions have been changed.
2639 dwLen = sizeof(DWORD);
2640 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2641 ok(result, "%08x\n", GetLastError());
2643 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2644 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2645 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2646 " got %08x\n", dwVal);
2648 CryptDestroyKey(hKey2);
2649 CryptDestroyKey(hKey1);
2651 clean_up_base_environment();
2654 static void test_key_initialization(void)
2657 HCRYPTPROV prov1, prov2;
2658 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2660 static BYTE abSessionKey[148] = {
2661 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2662 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2663 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2664 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2665 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2666 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2667 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2668 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2669 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2670 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2671 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2672 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2673 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2674 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2675 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2676 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2677 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2678 0x04, 0x8c, 0x49, 0x92
2681 /* Like init_base_environment, but doesn't generate new keys, as they'll
2682 * be imported instead.
2684 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2686 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2688 ok(result, "%08x\n", GetLastError());
2690 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2691 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2693 dwLen = (DWORD)sizeof(abSessionKey);
2694 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2695 ok(result, "%08x\n", GetLastError());
2697 /* Once the key has been imported, subsequently acquiring a context with
2698 * the same name will allow retrieving the key.
2700 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2701 ok(result, "%08x\n", GetLastError());
2702 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2703 ok(result, "%08x\n", GetLastError());
2704 if (result) CryptDestroyKey(hKey);
2705 CryptReleaseContext(prov2, 0);
2707 CryptDestroyKey(hSessionKey);
2708 CryptDestroyKey(hKeyExchangeKey);
2709 CryptReleaseContext(prov1, 0);
2710 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2711 CRYPT_DELETEKEYSET);
2716 if (!init_base_environment(0))
2728 test_block_cipher_modes();
2729 test_import_private();
2730 test_verify_signature();
2732 test_import_export();
2733 test_enum_container();
2734 clean_up_base_environment();
2735 test_key_permissions();
2736 test_key_initialization();
2737 test_schannel_provider();
2738 test_null_provider();
2739 test_rsa_round_trip();
2740 if (!init_aes_environment())
2746 clean_up_aes_environment();