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