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);
747 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == ERROR_NO_TOKEN /* Win7 */),
748 "expected NTE_BAD_KEY or ERROR_NO_TOKEN, got %08x\n", GetLastError());
751 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
752 ok(result, "%08x\n", GetLastError());
754 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
755 ok(result, "%08x\n", GetLastError());
759 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
761 dwLen = cTestData[i].enclen;
762 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
763 ok(result, "%08x\n", GetLastError());
764 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
766 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
767 ok(result, "%08x\n", GetLastError());
768 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
769 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
770 if((dwLen != cTestData[i].enclen) ||
771 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
773 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
774 printBytes("got",pbData,dwLen);
777 result = CryptDestroyKey(hKey);
778 ok(result, "%08x\n", GetLastError());
781 static void test_sha2(void)
783 static const unsigned char sha256hash[32] = {
784 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
785 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
786 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
789 static const unsigned char sha384hash[48] = {
790 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
791 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
792 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
793 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
794 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
796 static const unsigned char sha512hash[64] = {
797 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
798 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
799 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
800 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
801 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
802 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
803 0xb7, 0xf4, 0x81, 0xd4
805 unsigned char pbData[2048];
808 BYTE pbHashValue[64];
812 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
815 SetLastError(0xdeadbeef);
816 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
817 if (!result && GetLastError() == NTE_BAD_ALGID) {
818 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
821 ok(result, "%08x\n", GetLastError());
824 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
825 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
827 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
828 ok(result, "%08x\n", GetLastError());
831 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
832 ok(result, "%08x\n", GetLastError());
834 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
836 result = CryptDestroyHash(hHash);
837 ok(result, "%08x\n", GetLastError());
841 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
842 ok(result, "%08x\n", GetLastError());
845 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
846 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
848 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
849 ok(result, "%08x\n", GetLastError());
852 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
853 ok(result, "%08x\n", GetLastError());
855 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
857 result = CryptDestroyHash(hHash);
858 ok(result, "%08x\n", GetLastError());
862 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
863 ok(result, "%08x\n", GetLastError());
866 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
867 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
869 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
870 ok(result, "%08x\n", GetLastError());
873 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
874 ok(result, "%08x\n", GetLastError());
876 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
878 result = CryptDestroyHash(hHash);
879 ok(result, "%08x\n", GetLastError());
883 static void test_rc2(void)
885 static const BYTE rc2_40_encrypted[16] = {
886 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
887 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
888 static const BYTE rc2_128_encrypted[] = {
889 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
894 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
896 unsigned char pbData[2000], pbHashValue[16];
899 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
902 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
904 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
906 CRYPT_INTEGER_BLOB salt;
908 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
909 ok(result, "%08x\n", GetLastError());
912 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
913 ok(result, "%08x\n", GetLastError());
915 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
916 ok(result, "%08x\n", GetLastError());
918 dwLen = sizeof(DWORD);
919 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
920 ok(result, "%08x\n", GetLastError());
922 dwMode = CRYPT_MODE_CBC;
923 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
924 ok(result, "%08x\n", GetLastError());
926 dwLen = sizeof(DWORD);
927 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
928 ok(result, "%08x\n", GetLastError());
930 dwModeBits = 0xdeadbeef;
931 dwLen = sizeof(DWORD);
932 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
933 ok(result, "%08x\n", GetLastError());
935 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
936 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
937 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
938 " got %08x\n", dwModeBits);
940 dwLen = sizeof(DWORD);
941 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
942 ok(result, "%08x\n", GetLastError());
944 dwLen = sizeof(DWORD);
945 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
946 ok(result, "%08x\n", GetLastError());
948 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
949 ok(result, "%08x\n", GetLastError());
950 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
951 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
952 HeapFree(GetProcessHeap(), 0, pbTemp);
954 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
955 ok(result, "%08x\n", GetLastError());
956 /* The default salt length is always 11... */
957 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
958 /* and the default salt is always empty. */
959 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
960 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
961 for (i=0; i<dwLen; i++)
962 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
963 HeapFree(GetProcessHeap(), 0, pbTemp);
965 dwLen = sizeof(DWORD);
966 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
968 result = CryptDestroyHash(hHash);
969 ok(result, "%08x\n", GetLastError());
972 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
973 ok(result, "%08x\n", GetLastError());
975 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
977 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
978 ok(result, "%08x\n", GetLastError());
979 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
980 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
981 HeapFree(GetProcessHeap(), 0, pbTemp);
983 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
984 ok(result, "%08x\n", GetLastError());
986 /* Setting the salt also succeeds... */
987 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
988 ok(result, "setting salt failed: %08x\n", GetLastError());
989 /* but the resulting salt length is now zero? */
991 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
992 ok(result, "%08x\n", GetLastError());
993 ok(dwLen == 0, "unexpected salt length %d\n", dwLen);
994 /* What sizes salt can I set? */
995 salt.pbData = pbData;
999 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1000 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1001 /* The returned salt length is the same as the set salt length */
1002 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1003 ok(result, "%08x\n", GetLastError());
1004 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1007 SetLastError(0xdeadbeef);
1008 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1010 broken(result), /* Win9x, WinMe, NT4, W2K */
1011 "%08x\n", GetLastError());
1013 result = CryptDestroyKey(hKey);
1014 ok(result, "%08x\n", GetLastError());
1017 /* Again, but test setting the effective key len */
1018 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1020 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1022 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1024 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1025 ok(result, "%08x\n", GetLastError());
1028 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1029 ok(result, "%08x\n", GetLastError());
1031 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1032 ok(result, "%08x\n", GetLastError());
1034 SetLastError(0xdeadbeef);
1035 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1036 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1038 SetLastError(0xdeadbeef);
1039 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1040 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1042 SetLastError(0xdeadbeef);
1043 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1045 dwLen = sizeof(dwKeyLen);
1046 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1047 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1048 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1049 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1052 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1053 ok(result, "%d\n", GetLastError());
1055 dwLen = sizeof(dwKeyLen);
1056 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1057 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1058 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1059 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1061 result = CryptDestroyHash(hHash);
1062 ok(result, "%08x\n", GetLastError());
1065 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1066 ok(result, "%08x\n", GetLastError());
1068 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1069 "RC2 encryption failed!\n");
1071 /* Oddly enough this succeeds, though it should have no effect */
1073 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1074 ok(result, "%d\n", GetLastError());
1076 result = CryptDestroyKey(hKey);
1077 ok(result, "%08x\n", GetLastError());
1081 static void test_rc4(void)
1083 static const BYTE rc4[16] = {
1084 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1085 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1089 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1090 unsigned char pbData[2000], *pbTemp;
1091 unsigned char pszBuffer[256];
1094 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1097 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1099 /* rsaenh compiled without OpenSSL */
1100 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1102 CRYPT_INTEGER_BLOB salt;
1104 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1105 ok(result, "%08x\n", GetLastError());
1108 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1109 ok(result, "%08x\n", GetLastError());
1111 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1112 ok(result, "%08x\n", GetLastError());
1114 dwLen = sizeof(DWORD);
1115 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1116 ok(result, "%08x\n", GetLastError());
1118 dwLen = sizeof(DWORD);
1119 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1120 ok(result, "%08x\n", GetLastError());
1122 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1123 ok(result, "%08x\n", GetLastError());
1124 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1125 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1126 HeapFree(GetProcessHeap(), 0, pbTemp);
1128 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1129 ok(result, "%08x\n", GetLastError());
1130 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1131 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1132 HeapFree(GetProcessHeap(), 0, pbTemp);
1134 dwLen = sizeof(DWORD);
1135 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1137 result = CryptDestroyHash(hHash);
1138 ok(result, "%08x\n", GetLastError());
1141 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1142 ok(result, "%08x\n", GetLastError());
1144 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1145 ok(result, "%08x\n", GetLastError());
1147 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1149 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1150 ok(result, "%08x\n", GetLastError());
1152 /* Setting the salt also succeeds... */
1153 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1154 ok(result, "setting salt failed: %08x\n", GetLastError());
1155 /* but the resulting salt length is now zero? */
1157 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1158 ok(result, "%08x\n", GetLastError());
1159 ok(dwLen == 0, "unexpected salt length %d\n", dwLen);
1160 /* What sizes salt can I set? */
1161 salt.pbData = pbData;
1162 for (i=0; i<24; i++)
1165 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1166 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1167 /* The returned salt length is the same as the set salt length */
1168 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1169 ok(result, "%08x\n", GetLastError());
1170 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1173 SetLastError(0xdeadbeef);
1174 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1176 broken(result), /* Win9x, WinMe, NT4, W2K */
1177 "%08x\n", GetLastError());
1179 result = CryptDestroyKey(hKey);
1180 ok(result, "%08x\n", GetLastError());
1184 static void test_hmac(void) {
1188 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1189 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1192 static const BYTE hmac[16] = {
1193 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1194 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1197 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1199 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1201 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1202 ok(result, "%08x\n", GetLastError());
1203 if (!result) return;
1205 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1206 ok(result, "%08x\n", GetLastError());
1208 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1209 ok(result, "%08x\n", GetLastError());
1211 dwLen = sizeof(abData)/sizeof(BYTE);
1212 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1213 ok(result, "%08x\n", GetLastError());
1215 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1217 result = CryptDestroyHash(hHash);
1218 ok(result, "%08x\n", GetLastError());
1220 result = CryptDestroyKey(hKey);
1221 ok(result, "%08x\n", GetLastError());
1223 /* Provoke errors */
1224 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1225 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1228 static void test_mac(void) {
1233 BYTE abData[256], abEnc[264];
1234 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1237 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1238 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1240 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1243 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1244 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1246 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1247 ok(result, "%08x\n", GetLastError());
1248 if (!result) return;
1250 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1251 ok(result, "%08x\n", GetLastError());
1253 dwLen = sizeof(abData)/sizeof(BYTE);
1254 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1255 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1257 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1259 result = CryptDestroyHash(hHash);
1260 ok(result, "%08x\n", GetLastError());
1262 result = CryptDestroyKey(hKey);
1263 ok(result, "%08x\n", GetLastError());
1265 /* Provoke errors */
1266 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1268 SetLastError(0xdeadbeef);
1269 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1270 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1271 broken(result), /* Win9x, WinMe, NT4, W2K */
1272 "%08x\n", GetLastError());
1274 result = CryptDestroyKey(hKey);
1275 ok(result, "%08x\n", GetLastError());
1278 static BYTE abPlainPrivateKey[596] = {
1279 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1280 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1281 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1282 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1283 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1284 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1285 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1286 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1287 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1288 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1289 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1290 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1291 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1292 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1293 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1294 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1295 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1296 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1297 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1298 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1299 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1300 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1301 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1302 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1303 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1304 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1305 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1306 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1307 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1308 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1309 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1310 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1311 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1312 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1313 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1314 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1315 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1316 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1317 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1318 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1319 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1320 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1321 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1322 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1323 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1324 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1325 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1326 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1327 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1328 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1329 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1330 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1331 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1332 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1333 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1334 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1335 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1336 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1337 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1338 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1339 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1340 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1341 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1342 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1343 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1344 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1345 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1346 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1347 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1348 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1349 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1350 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1351 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1352 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1353 0xf2, 0x5d, 0x58, 0x07
1356 static void test_import_private(void)
1359 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1361 static BYTE abSessionKey[148] = {
1362 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1363 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1364 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1365 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1366 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1367 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1368 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1369 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1370 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1371 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1372 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1373 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1374 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1375 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1376 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1377 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1378 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1379 0x04, 0x8c, 0x49, 0x92
1381 static BYTE abEncryptedMessage[12] = {
1382 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1383 0x1c, 0xfd, 0xde, 0x71
1386 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1387 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1389 /* rsaenh compiled without OpenSSL */
1390 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1394 dwLen = (DWORD)sizeof(abSessionKey);
1395 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1396 ok(result, "%08x\n", GetLastError());
1397 if (!result) return;
1400 dwLen = sizeof(DWORD);
1401 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1402 ok(result, "%08x\n", GetLastError());
1404 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1405 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1406 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1407 " got %08x\n", dwVal);
1409 dwLen = (DWORD)sizeof(abEncryptedMessage);
1410 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1411 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1412 "%08x, len: %d\n", GetLastError(), dwLen);
1413 CryptDestroyKey(hSessionKey);
1415 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1417 dwLen = (DWORD)sizeof(abSessionKey);
1418 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1419 ok(result, "%08x\n", GetLastError());
1420 CryptDestroyKey(hSessionKey);
1421 if (!result) return;
1423 dwLen = (DWORD)sizeof(abSessionKey);
1424 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1425 ok(result, "%08x\n", GetLastError());
1426 if (!result) return;
1428 CryptDestroyKey(hSessionKey);
1429 CryptDestroyKey(hKeyExchangeKey);
1432 static void test_verify_signature(void) {
1434 HCRYPTKEY hPubSignKey;
1435 BYTE abData[] = "Wine rocks!";
1437 BYTE abPubKey[148] = {
1438 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1439 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1440 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1441 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1442 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1443 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1444 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1445 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1446 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1447 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1448 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1449 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1450 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1451 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1452 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1453 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1454 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1455 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1456 0xe1, 0x21, 0x50, 0xac
1458 /* md2 with hash oid */
1459 BYTE abSignatureMD2[128] = {
1460 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1461 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1462 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1463 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1464 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1465 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1466 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1467 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1468 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1469 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1470 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1471 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1472 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1473 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1474 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1475 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1477 /* md2 without hash oid */
1478 BYTE abSignatureMD2NoOID[128] = {
1479 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1480 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1481 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1482 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1483 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1484 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1485 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1486 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1487 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1488 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1489 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1490 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1491 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1492 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1493 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1494 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1496 /* md4 with hash oid */
1497 BYTE abSignatureMD4[128] = {
1498 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1499 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1500 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1501 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1502 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1503 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1504 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1505 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1506 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1507 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1508 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1509 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1510 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1511 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1512 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1513 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1515 /* md4 without hash oid */
1516 BYTE abSignatureMD4NoOID[128] = {
1517 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1518 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1519 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1520 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1521 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1522 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1523 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1524 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1525 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1526 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1527 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1528 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1529 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1530 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1531 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1532 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1534 /* md5 with hash oid */
1535 BYTE abSignatureMD5[128] = {
1536 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1537 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1538 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1539 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1540 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1541 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1542 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1543 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1544 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1545 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1546 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1547 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1548 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1549 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1550 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1551 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1553 /* md5 without hash oid */
1554 BYTE abSignatureMD5NoOID[128] = {
1555 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1556 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1557 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1558 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1559 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1560 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1561 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1562 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1563 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1564 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1565 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1566 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1567 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1568 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1569 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1570 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1572 /* sha with hash oid */
1573 BYTE abSignatureSHA[128] = {
1574 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1575 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1576 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1577 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1578 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1579 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1580 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1581 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1582 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1583 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1584 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1585 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1586 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1587 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1588 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1589 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1591 /* sha without hash oid */
1592 BYTE abSignatureSHANoOID[128] = {
1593 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1594 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1595 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1596 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1597 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1598 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1599 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1600 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1601 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1602 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1603 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1604 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1605 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1606 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1607 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1608 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1611 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1612 ok(result, "%08x\n", GetLastError());
1613 if (!result) return;
1615 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1616 ok(result, "%08x\n", GetLastError());
1617 if (!result) return;
1619 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1620 ok(result, "%08x\n", GetLastError());
1621 if (!result) return;
1623 /*check that a NULL pointer signature is correctly handled*/
1624 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1625 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1626 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1629 /* check that we get a bad signature error when the signature is too short*/
1630 SetLastError(0xdeadbeef);
1631 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1632 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1633 broken(result), /* Win9x, WinMe, NT4 */
1634 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1636 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1637 ok(result, "%08x\n", GetLastError());
1638 if (!result) return;
1640 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1641 ok(result, "%08x\n", GetLastError());
1642 if (!result) return;
1644 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1645 * the OID at all. */
1646 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1647 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1648 if (result) return;*/
1650 CryptDestroyHash(hHash);
1652 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1653 ok(result, "%08x\n", GetLastError());
1654 if (!result) return;
1656 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1657 ok(result, "%08x\n", GetLastError());
1658 if (!result) return;
1660 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1661 ok(result, "%08x\n", GetLastError());
1662 if (!result) return;
1664 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1665 ok(result, "%08x\n", GetLastError());
1666 if (!result) return;
1668 CryptDestroyHash(hHash);
1670 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1671 ok(result, "%08x\n", GetLastError());
1672 if (!result) return;
1674 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1675 ok(result, "%08x\n", GetLastError());
1676 if (!result) return;
1678 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1679 ok(result, "%08x\n", GetLastError());
1680 if (!result) return;
1682 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1683 ok(result, "%08x\n", GetLastError());
1684 if (!result) return;
1686 CryptDestroyHash(hHash);
1688 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1689 ok(result, "%08x\n", GetLastError());
1690 if (!result) return;
1692 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1693 ok(result, "%08x\n", GetLastError());
1694 if (!result) return;
1696 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1697 ok(result, "%08x\n", GetLastError());
1698 if (!result) return;
1700 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1701 ok(result, "%08x\n", GetLastError());
1702 if (!result) return;
1704 CryptDestroyHash(hHash);
1705 CryptDestroyKey(hPubSignKey);
1708 static void test_rsa_encrypt(void)
1711 BYTE abData[2048] = "Wine rocks!";
1715 /* It is allowed to use the key exchange key for encryption/decryption */
1716 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1717 ok (result, "%08x\n", GetLastError());
1718 if (!result) return;
1721 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1722 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1723 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1725 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1726 ok (result, "%08x\n", GetLastError());
1727 if (!result) return;
1729 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1730 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1733 dwLen = sizeof(DWORD);
1734 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1735 ok(result, "%08x\n", GetLastError());
1737 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1738 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1739 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1740 " got %08x\n", dwVal);
1742 /* An RSA key doesn't support salt */
1743 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1744 ok(!result && GetLastError() == NTE_BAD_KEY,
1745 "expected NTE_BAD_KEY, got %08x\n", GetLastError());
1747 /* The key exchange key's public key may be exported.. */
1748 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1749 ok(result, "%08x\n", GetLastError());
1750 /* but its private key may not be. */
1751 SetLastError(0xdeadbeef);
1752 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1753 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1754 broken(result), /* Win9x/NT4 */
1755 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1756 /* Setting the permissions of the key exchange key isn't allowed, either. */
1757 dwVal |= CRYPT_EXPORT;
1758 SetLastError(0xdeadbeef);
1759 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1761 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1762 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1764 CryptDestroyKey(hRSAKey);
1766 /* It is not allowed to use the signature key for encryption/decryption */
1767 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1768 ok (result, "%08x\n", GetLastError());
1769 if (!result) return;
1772 dwLen = sizeof(DWORD);
1773 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1774 ok(result, "%08x\n", GetLastError());
1776 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1777 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1778 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1779 " got %08x\n", dwVal);
1781 /* The signature key's public key may also be exported.. */
1782 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1783 ok(result, "%08x\n", GetLastError());
1784 /* but its private key may not be. */
1785 SetLastError(0xdeadbeef);
1786 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1787 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1788 broken(result), /* Win9x/NT4 */
1789 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1790 /* Setting the permissions of the signature key isn't allowed, either. */
1791 dwVal |= CRYPT_EXPORT;
1792 SetLastError(0xdeadbeef);
1793 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1795 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1796 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1799 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1800 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1802 CryptDestroyKey(hRSAKey);
1805 static void test_import_export(void)
1807 DWORD dwLen, dwDataLen, dwVal;
1808 HCRYPTKEY hPublicKey, hPrivKey;
1811 BYTE emptyKey[2048], *exported_key;
1812 static BYTE abPlainPublicKey[84] = {
1813 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1814 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1815 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1816 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1817 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1818 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1819 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1820 0x11, 0x11, 0x11, 0x11, 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
1825 static BYTE priv_key_with_high_bit[] = {
1826 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1827 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1828 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1829 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1830 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1831 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1832 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1833 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1834 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1835 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1836 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1837 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1838 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1839 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1840 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1841 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1842 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1843 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1844 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1845 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1846 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1847 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1848 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1849 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1850 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1851 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1852 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1853 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1854 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1855 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1856 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1857 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1858 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1859 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1860 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1861 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1862 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1863 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1864 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1865 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1866 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1867 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1868 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1869 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1870 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1871 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1872 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1873 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1874 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1875 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1876 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1877 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1878 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1879 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1880 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1881 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1882 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1883 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1884 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1885 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1886 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1887 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1888 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1889 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1890 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1891 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1892 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1893 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1894 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1895 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1896 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1897 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1898 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1899 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1900 0xb6, 0x5f, 0x01, 0x5e
1902 static const BYTE expected_exported_priv_key[] = {
1903 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1904 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1905 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1906 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1907 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1908 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1909 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1910 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1911 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1912 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1913 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1914 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1915 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1916 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1917 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1918 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1919 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1920 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1921 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1922 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1923 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1924 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1925 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1926 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1927 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1928 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1929 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1930 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1931 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1932 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1933 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1934 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1935 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1936 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1937 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1938 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1939 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1940 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1941 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1942 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1943 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1944 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1945 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1946 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1947 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1948 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1949 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1950 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1951 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1952 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1953 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1954 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1955 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1956 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1957 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1958 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1959 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1960 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1961 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1962 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1963 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1964 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1965 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1966 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1967 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1968 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1969 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1970 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1971 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1972 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1973 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1974 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1975 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1976 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1977 0xb6, 0x5f, 0x01, 0x5e
1981 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1982 ok(result, "failed to import the public key\n");
1984 dwDataLen=sizeof(algID);
1985 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1986 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1987 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1990 dwDataLen = sizeof(DWORD);
1991 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
1992 ok(result, "%08x\n", GetLastError());
1994 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1995 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1996 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1997 " got %08x\n", dwVal);
1998 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1999 ok(result, "failed to export the fresh imported public key\n");
2000 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2001 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2003 CryptDestroyKey(hPublicKey);
2005 result = CryptImportKey(hProv, priv_key_with_high_bit,
2006 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2007 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2009 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2010 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2011 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2012 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2014 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2016 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2018 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2019 "unexpected value\n");
2021 HeapFree(GetProcessHeap(), 0, exported_key);
2023 CryptDestroyKey(hPrivKey);
2026 static void test_schannel_provider(void)
2029 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2030 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2033 SCHANNEL_ALG saSChannelAlg;
2034 CRYPT_DATA_BLOB data_blob;
2035 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2036 BYTE abTLS1Master[140] = {
2037 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2038 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2039 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2040 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2041 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2042 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2043 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2044 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2045 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2046 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2047 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2048 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2049 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2050 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2051 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2052 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2053 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2054 0xd3, 0x1e, 0x82, 0xb3
2056 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2057 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2058 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2059 BYTE abClientFinished[16] = "client finished";
2060 BYTE abData[16] = "Wine rocks!";
2062 static const BYTE abEncryptedData[16] = {
2063 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2064 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2066 static const BYTE abPRF[16] = {
2067 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2068 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2070 static const BYTE abMD5[16] = {
2071 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2072 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2075 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2078 win_skip("no PROV_RSA_SCHANNEL support\n");
2081 ok (result, "%08x\n", GetLastError());
2083 CryptReleaseContext(hProv, 0);
2085 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2086 ok (result, "%08x\n", GetLastError());
2087 if (!result) return;
2089 /* To get deterministic results, we import the TLS1 master secret (which
2090 * is typically generated from a random generator). Therefore, we need
2092 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2093 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2094 ok (result, "%08x\n", GetLastError());
2095 if (!result) return;
2097 dwLen = (DWORD)sizeof(abTLS1Master);
2098 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2099 ok (result, "%08x\n", GetLastError());
2100 if (!result) return;
2102 /* Setting the TLS1 client and server random parameters, as well as the
2103 * MAC and encryption algorithm parameters. */
2104 data_blob.cbData = 33;
2105 data_blob.pbData = abClientSecret;
2106 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2107 ok (result, "%08x\n", GetLastError());
2108 if (!result) return;
2110 data_blob.cbData = 33;
2111 data_blob.pbData = abServerSecret;
2112 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2113 ok (result, "%08x\n", GetLastError());
2114 if (!result) return;
2116 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2117 saSChannelAlg.Algid = CALG_DES;
2118 saSChannelAlg.cBits = 64;
2119 saSChannelAlg.dwFlags = 0;
2120 saSChannelAlg.dwReserved = 0;
2121 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2122 ok (result, "%08x\n", GetLastError());
2123 if (!result) return;
2125 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2126 saSChannelAlg.Algid = CALG_MD5;
2127 saSChannelAlg.cBits = 128;
2128 saSChannelAlg.dwFlags = 0;
2129 saSChannelAlg.dwReserved = 0;
2130 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2131 ok (result, "%08x\n", GetLastError());
2132 if (!result) return;
2134 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2135 * (Keys can only be derived from hashes, not from other keys.) */
2136 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2137 ok (result, "%08x\n", GetLastError());
2138 if (!result) return;
2140 /* Deriving the server write encryption key from the master hash */
2141 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2142 ok (result, "%08x\n", GetLastError());
2143 if (!result) return;
2145 /* Encrypting some data with the server write encryption key and checking the result. */
2147 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2148 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2150 /* Second test case: Test the TLS1 pseudo random number function. */
2151 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2152 ok (result, "%08x\n", GetLastError());
2153 if (!result) return;
2155 /* Set the label and seed parameters for the random number function */
2156 data_blob.cbData = 36;
2157 data_blob.pbData = abHashedHandshakes;
2158 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2159 ok (result, "%08x\n", GetLastError());
2160 if (!result) return;
2162 data_blob.cbData = 15;
2163 data_blob.pbData = abClientFinished;
2164 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2165 ok (result, "%08x\n", GetLastError());
2166 if (!result) return;
2168 /* Generate some pseudo random bytes and check if they are correct. */
2169 dwLen = (DWORD)sizeof(abData);
2170 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2171 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2172 "%08x\n", GetLastError());
2174 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2175 * Hash some data with the HMAC. Compare results. */
2176 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2177 ok (result, "%08x\n", GetLastError());
2178 if (!result) return;
2180 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2181 ok (result, "%08x\n", GetLastError());
2182 if (!result) return;
2184 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2185 ok (result, "%08x\n", GetLastError());
2186 if (!result) return;
2188 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2189 ok (result, "%08x\n", GetLastError());
2190 if (!result) return;
2192 dwLen = (DWORD)sizeof(abMD5Hash);
2193 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2194 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2196 CryptDestroyHash(hHMAC);
2197 CryptDestroyHash(hTLS1PRF);
2198 CryptDestroyHash(hMasterHash);
2199 CryptDestroyKey(hServerWriteMACKey);
2200 CryptDestroyKey(hServerWriteKey);
2201 CryptDestroyKey(hRSAKey);
2202 CryptDestroyKey(hMasterSecret);
2203 CryptReleaseContext(hProv, 0);
2204 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2207 /* Test that a key can be used to encrypt data and exported, and that, when
2208 * the exported key is imported again, can be used to decrypt the original
2211 static void test_rsa_round_trip(void)
2213 static const char test_string[] = "Well this is a fine how-do-you-do.";
2215 HCRYPTKEY signKey, keyExchangeKey;
2217 BYTE data[256], *exportedKey;
2218 DWORD dataLen, keyLen;
2220 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2221 CRYPT_DELETEKEYSET);
2223 /* Generate a new key... */
2224 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2226 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2227 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2228 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2229 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2230 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2231 /* encrypt some data with it... */
2232 memcpy(data, test_string, strlen(test_string) + 1);
2233 dataLen = strlen(test_string) + 1;
2234 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2236 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2237 "CryptEncrypt failed: %08x\n", GetLastError());
2238 /* export the key... */
2239 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2241 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2242 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2243 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2245 /* destroy the key... */
2246 CryptDestroyKey(keyExchangeKey);
2247 CryptDestroyKey(signKey);
2248 /* import the key again... */
2249 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2250 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2251 HeapFree(GetProcessHeap(), 0, exportedKey);
2252 /* and decrypt the data encrypted with the original key with the imported
2255 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2256 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2257 "CryptDecrypt failed: %08x\n", GetLastError());
2260 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2261 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2263 CryptDestroyKey(keyExchangeKey);
2264 CryptReleaseContext(prov, 0);
2266 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2267 CRYPT_DELETEKEYSET);
2270 static void test_enum_container(void)
2272 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2274 BOOL result, fFound = FALSE;
2276 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2277 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2278 SetLastError(0xdeadbeef);
2279 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2280 ok (result, "%08x\n", GetLastError());
2281 ok (dwBufferLen == MAX_PATH + 1 ||
2282 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2283 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2285 /* If the result fits into abContainerName dwBufferLen is left untouched */
2286 dwBufferLen = (DWORD)sizeof(abContainerName);
2287 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2288 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2290 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2292 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2293 dwBufferLen = (DWORD)sizeof(abContainerName);
2294 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2296 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2299 static BYTE signBlob[] = {
2300 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2301 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2302 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2303 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2304 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2305 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2306 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2307 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2308 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2309 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2310 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2311 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2312 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2313 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2314 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2315 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2316 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2317 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2318 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2319 0xb6,0x85,0x86,0x07 };
2321 static void test_null_provider(void)
2326 DWORD keySpec, dataLen,dwParam;
2327 char szName[MAX_PATH];
2329 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2330 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2331 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2332 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2333 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2334 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2335 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2336 CRYPT_DELETEKEYSET);
2337 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2338 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2339 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2340 CRYPT_DELETEKEYSET);
2341 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2342 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2343 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2344 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2345 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2347 /* Delete the default container. */
2348 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2349 /* Once you've deleted the default container you can't open it as if it
2352 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2353 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2354 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2355 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2356 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2357 CRYPT_VERIFYCONTEXT);
2358 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2359 if (!result) return;
2360 dataLen = sizeof(keySpec);
2361 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2363 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2364 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2365 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2366 * supported, you can't get the keys from this container.
2368 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2369 ok(!result && GetLastError() == NTE_NO_KEY,
2370 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2371 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2372 ok(!result && GetLastError() == NTE_NO_KEY,
2373 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2374 result = CryptReleaseContext(prov, 0);
2375 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2376 /* You can create a new default container. */
2377 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2379 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2380 /* But you still can't get the keys (until one's been generated.) */
2381 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2382 ok(!result && GetLastError() == NTE_NO_KEY,
2383 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2384 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2385 ok(!result && GetLastError() == NTE_NO_KEY,
2386 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2387 CryptReleaseContext(prov, 0);
2388 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2390 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2391 CRYPT_DELETEKEYSET);
2392 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2393 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2394 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2395 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2396 CRYPT_VERIFYCONTEXT);
2397 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2398 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2399 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2401 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2402 if (!result) return;
2403 /* Test provider parameters getter */
2404 dataLen = sizeof(dwParam);
2405 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2406 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2407 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2408 dataLen = sizeof(dwParam);
2409 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2410 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2411 "Expected 0, got 0x%08X\n",dwParam);
2412 dataLen = sizeof(dwParam);
2413 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2414 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2415 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2416 dataLen = sizeof(keySpec);
2417 SetLastError(0xdeadbeef);
2418 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2419 if (!result && GetLastError() == NTE_BAD_TYPE)
2420 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2422 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2423 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2424 /* PP_CONTAINER parameter */
2425 dataLen = sizeof(szName);
2426 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2427 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2428 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2429 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2430 /* PP_UNIQUE_CONTAINER parameter */
2431 dataLen = sizeof(szName);
2432 SetLastError(0xdeadbeef);
2433 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2434 if (!result && GetLastError() == NTE_BAD_TYPE)
2436 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2440 char container[MAX_PATH];
2442 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2443 uniquecontainer(container);
2446 ok(dataLen == strlen(container)+1 ||
2447 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2448 "Expected a param length of 70, got %d\n", dataLen);
2449 ok(!strcmp(container, szName) ||
2450 broken(!strcmp(szName, szContainer)) /* WinME */,
2451 "Wrong container name : %s\n", szName);
2454 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2455 ok(!result && GetLastError() == NTE_NO_KEY,
2456 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2457 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2458 ok(!result && GetLastError() == NTE_NO_KEY,
2459 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2461 /* Importing a key exchange blob.. */
2462 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2464 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2465 CryptDestroyKey(key);
2466 /* allows access to the key exchange key.. */
2467 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2468 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2469 CryptDestroyKey(key);
2470 /* but not to the private key. */
2471 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2472 ok(!result && GetLastError() == NTE_NO_KEY,
2473 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2474 CryptReleaseContext(prov, 0);
2475 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2476 CRYPT_DELETEKEYSET);
2478 /* Whereas importing a sign blob.. */
2479 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2481 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2482 if (!result) return;
2483 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2484 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2485 CryptDestroyKey(key);
2486 /* doesn't allow access to the key exchange key.. */
2487 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2488 ok(!result && GetLastError() == NTE_NO_KEY,
2489 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2490 /* but does to the private key. */
2491 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2492 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2493 CryptDestroyKey(key);
2494 CryptReleaseContext(prov, 0);
2496 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2497 CRYPT_DELETEKEYSET);
2499 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2500 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2502 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2503 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2504 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2505 CryptDestroyKey(key);
2506 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2507 ok(!result, "expected CryptGetUserKey to fail\n");
2508 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2509 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2510 CryptDestroyKey(key);
2511 CryptReleaseContext(prov, 0);
2513 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2514 CRYPT_DELETEKEYSET);
2516 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2517 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2519 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2520 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2521 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2522 CryptDestroyKey(key);
2523 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2524 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2525 CryptDestroyKey(key);
2526 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2527 ok(!result, "expected CryptGetUserKey to fail\n");
2528 CryptReleaseContext(prov, 0);
2530 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2531 CRYPT_DELETEKEYSET);
2533 /* test for the bug in accessing the user key in a container
2535 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2537 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2538 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2539 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2540 CryptDestroyKey(key);
2541 CryptReleaseContext(prov,0);
2542 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2543 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2544 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2545 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2546 CryptDestroyKey(key);
2547 CryptReleaseContext(prov, 0);
2549 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2550 CRYPT_DELETEKEYSET);
2552 /* test the machine key set */
2553 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2554 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2555 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2556 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2557 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2558 CryptReleaseContext(prov, 0);
2559 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2560 CRYPT_MACHINE_KEYSET);
2561 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2562 CryptReleaseContext(prov,0);
2563 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2564 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2565 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2567 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2568 CRYPT_MACHINE_KEYSET);
2569 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2570 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2574 static void test_key_permissions(void)
2576 HCRYPTKEY hKey1, hKey2;
2580 /* Create keys that are exportable */
2581 if (!init_base_environment(CRYPT_EXPORTABLE))
2584 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2585 ok (result, "%08x\n", GetLastError());
2586 if (!result) return;
2589 dwLen = sizeof(DWORD);
2590 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2591 ok(result, "%08x\n", GetLastError());
2593 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2594 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2595 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2596 " got %08x\n", dwVal);
2598 /* The key exchange key's public key may be exported.. */
2599 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2600 ok(result, "%08x\n", GetLastError());
2601 /* and its private key may be too. */
2602 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2603 ok(result, "%08x\n", GetLastError());
2604 /* Turning off the key's export permissions is "allowed".. */
2605 dwVal &= ~CRYPT_EXPORT;
2606 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2608 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2609 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2610 "%08x\n", GetLastError());
2611 /* but it has no effect. */
2613 dwLen = sizeof(DWORD);
2614 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2615 ok(result, "%08x\n", GetLastError());
2617 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2618 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2619 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2620 " got %08x\n", dwVal);
2621 /* Thus, changing the export flag of the key doesn't affect whether the key
2624 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2625 ok(result, "%08x\n", GetLastError());
2627 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2628 ok (result, "%08x\n", GetLastError());
2630 /* A subsequent get of the same key, into a different handle, also doesn't
2631 * show that the permissions have been changed.
2634 dwLen = sizeof(DWORD);
2635 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2636 ok(result, "%08x\n", GetLastError());
2638 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2639 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2640 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2641 " got %08x\n", dwVal);
2643 CryptDestroyKey(hKey2);
2644 CryptDestroyKey(hKey1);
2646 clean_up_base_environment();
2649 static void test_key_initialization(void)
2652 HCRYPTPROV prov1, prov2;
2653 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2655 static BYTE abSessionKey[148] = {
2656 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2657 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2658 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2659 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2660 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2661 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2662 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2663 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2664 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2665 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2666 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2667 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2668 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2669 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2670 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2671 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2672 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2673 0x04, 0x8c, 0x49, 0x92
2676 /* Like init_base_environment, but doesn't generate new keys, as they'll
2677 * be imported instead.
2679 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2681 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2683 ok(result, "%08x\n", GetLastError());
2685 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2686 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2688 dwLen = (DWORD)sizeof(abSessionKey);
2689 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2690 ok(result, "%08x\n", GetLastError());
2692 /* Once the key has been imported, subsequently acquiring a context with
2693 * the same name will allow retrieving the key.
2695 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2696 ok(result, "%08x\n", GetLastError());
2697 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2698 ok(result, "%08x\n", GetLastError());
2699 if (result) CryptDestroyKey(hKey);
2700 CryptReleaseContext(prov2, 0);
2702 CryptDestroyKey(hSessionKey);
2703 CryptDestroyKey(hKeyExchangeKey);
2704 CryptReleaseContext(prov1, 0);
2705 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2706 CRYPT_DELETEKEYSET);
2711 if (!init_base_environment(0))
2723 test_block_cipher_modes();
2724 test_import_private();
2725 test_verify_signature();
2727 test_import_export();
2728 test_enum_container();
2729 clean_up_base_environment();
2730 test_key_permissions();
2731 test_key_initialization();
2732 test_schannel_provider();
2733 test_null_provider();
2734 test_rsa_round_trip();
2735 if (!init_aes_environment())
2741 clean_up_aes_environment();