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;
324 BYTE pbHashValue[36];
325 DWORD hashlen, len, error;
328 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
331 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
333 /* rsaenh compiled without OpenSSL */
334 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
336 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
337 ok(result, "%08x\n", GetLastError());
340 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
341 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
344 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
345 ok(result, "%08x\n", GetLastError());
347 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
349 result = CryptDestroyHash(hHash);
350 ok(result, "%08x\n", GetLastError());
354 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
355 ok(result, "%08x\n", GetLastError());
357 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
358 ok(result, "%08x\n", GetLastError());
361 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
362 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
365 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
366 ok(result, "%08x\n", GetLastError());
368 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
370 result = CryptDestroyHash(hHash);
371 ok(result, "%08x\n", GetLastError());
374 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
375 ok(result, "%08x\n", GetLastError());
378 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
379 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
381 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
382 ok(result, "%08x\n", GetLastError());
385 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
386 ok(result, "%08x\n", GetLastError());
388 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
390 result = CryptDestroyHash(hHash);
391 ok(result, "%08x\n", GetLastError());
393 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
394 ok(result, "%08x\n", GetLastError());
396 /* The hash is available even if CryptHashData hasn't been called */
398 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
399 ok(result, "%08x\n", GetLastError());
401 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
403 /* It's also stable: getting it twice results in the same value */
404 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
405 ok(result, "%08x\n", GetLastError());
407 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
409 /* Can't add data after the hash been retrieved */
410 SetLastError(0xdeadbeef);
411 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
412 ok(!result, "Expected failure\n");
413 ok(GetLastError() == NTE_BAD_HASH_STATE ||
414 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
415 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
417 /* You can still retrieve the hash, its value just hasn't changed */
418 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
419 ok(result, "%08x\n", GetLastError());
421 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
423 result = CryptDestroyHash(hHash);
424 ok(result, "%08x\n", GetLastError());
427 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
428 ok(result, "%08x\n", GetLastError());
430 result = CryptHashData(hHash, pbData, 5, 0);
431 ok(result, "%08x\n", GetLastError());
433 if(pCryptDuplicateHash) {
434 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
435 ok(result, "%08x\n", GetLastError());
437 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
438 ok(result, "%08x\n", GetLastError());
441 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
442 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
445 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
446 ok(result, "%08x\n", GetLastError());
448 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
450 result = CryptDestroyHash(hHashClone);
451 ok(result, "%08x\n", GetLastError());
454 result = CryptDestroyHash(hHash);
455 ok(result, "%08x\n", GetLastError());
457 /* The SHA-2 variants aren't supported in the RSA full provider */
458 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
459 ok(!result && GetLastError() == NTE_BAD_ALGID,
460 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
461 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
462 ok(!result && GetLastError() == NTE_BAD_ALGID,
463 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
464 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
465 ok(!result && GetLastError() == NTE_BAD_ALGID,
466 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
468 result = CryptAcquireContextW(&prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
469 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
471 result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash);
472 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
474 /* release provider before using the hash */
475 result = CryptReleaseContext(prov, 0);
476 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
478 SetLastError(0xdeadbeef);
479 result = CryptHashData(hHash, (BYTE *)"data", sizeof("data"), 0);
480 error = GetLastError();
481 ok(!result, "CryptHashData succeeded\n");
482 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
484 SetLastError(0xdeadbeef);
485 result = CryptDestroyHash(hHash);
486 error = GetLastError();
487 ok(!result, "CryptDestroyHash succeeded\n");
488 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
490 result = CryptAcquireContextW(&prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
491 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
493 result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
494 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
496 result = CryptHashData(hHash, (BYTE *)"data", sizeof("data"), 0);
497 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
499 result = CryptDuplicateHash(hHash, NULL, 0, &hHashClone);
500 ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
503 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
504 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
506 /* add data after duplicating the hash */
507 result = CryptHashData(hHash, (BYTE *)"more data", sizeof("more data"), 0);
508 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
510 result = CryptDestroyHash(hHash);
511 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
513 result = CryptDestroyHash(hHashClone);
514 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
516 result = CryptReleaseContext(prov, 0);
517 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
520 static void test_block_cipher_modes(void)
522 static const BYTE plain[23] = {
523 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
524 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
525 static const BYTE ecb[24] = {
526 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
527 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
528 static const BYTE cbc[24] = {
529 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
530 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
531 static const BYTE cfb[24] = {
532 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
533 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
539 result = derive_key(CALG_RC2, &hKey, 40);
542 memcpy(abData, plain, sizeof(plain));
544 dwMode = CRYPT_MODE_ECB;
545 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
546 ok(result, "%08x\n", GetLastError());
548 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
549 ok(result, "%08x\n", GetLastError());
550 ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
553 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
554 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
555 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
557 SetLastError(ERROR_SUCCESS);
559 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
560 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
561 "%08x, dwLen: %d\n", GetLastError(), dwLen);
563 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
564 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
565 "%08x, dwLen: %d\n", GetLastError(), dwLen);
567 dwMode = CRYPT_MODE_CBC;
568 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
569 ok(result, "%08x\n", GetLastError());
572 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
573 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
574 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
577 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
578 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
579 "%08x, dwLen: %d\n", GetLastError(), dwLen);
581 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
582 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
583 "%08x, dwLen: %d\n", GetLastError(), dwLen);
585 dwMode = CRYPT_MODE_CFB;
586 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
587 ok(result, "%08x\n", GetLastError());
590 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
591 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
594 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
595 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
596 "%08x, dwLen: %d\n", GetLastError(), dwLen);
599 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
600 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
603 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
604 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
605 "%08x, dwLen: %d\n", GetLastError(), dwLen);
607 dwMode = CRYPT_MODE_OFB;
608 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
609 ok(result, "%08x\n", GetLastError());
612 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
613 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
615 CryptDestroyKey(hKey);
618 static void test_3des112(void)
623 unsigned char pbData[16];
626 result = derive_key(CALG_3DES_112, &hKey, 0);
628 /* rsaenh compiled without OpenSSL */
629 ok(GetLastError() == NTE_BAD_ALGID, "%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[1].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);
662 result = CryptDestroyKey(hKey);
663 ok(result, "%08x\n", GetLastError());
666 static void test_des(void)
671 unsigned char pbData[16];
674 result = derive_key(CALG_DES, &hKey, 56);
676 /* rsaenh compiled without OpenSSL */
677 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
681 dwMode = CRYPT_MODE_ECB;
682 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
683 ok(result, "%08x\n", GetLastError());
685 dwLen = sizeof(DWORD);
686 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
687 ok(result, "%08x\n", GetLastError());
689 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
692 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
693 ok(result, "%08x\n", GetLastError());
695 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
696 ok(result, "%08x\n", GetLastError());
700 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
702 dwLen = cTestData[i].enclen;
703 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
704 ok(result, "%08x\n", GetLastError());
705 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
707 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
708 ok(result, "%08x\n", GetLastError());
709 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
710 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
711 if((dwLen != cTestData[i].enclen) ||
712 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
714 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
715 printBytes("got",pbData,dwLen);
719 result = CryptDestroyKey(hKey);
720 ok(result, "%08x\n", GetLastError());
723 static void test_3des(void)
728 unsigned char pbData[16];
729 static const BYTE des3[16] = {
730 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
731 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
734 result = derive_key(CALG_3DES, &hKey, 0);
737 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
740 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
741 ok(result, "%08x\n", GetLastError());
743 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
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[i].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_aes(int keylen)
777 unsigned char pbData[16];
783 result = derive_key(CALG_AES_256, &hKey, 0);
786 result = derive_key(CALG_AES_192, &hKey, 0);
790 result = derive_key(CALG_AES_128, &hKey, 0);
795 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
797 /* AES provider doesn't support salt */
798 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
799 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == ERROR_NO_TOKEN /* Win7 */),
800 "expected NTE_BAD_KEY or ERROR_NO_TOKEN, got %08x\n", GetLastError());
803 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
804 ok(result, "%08x\n", GetLastError());
806 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
807 ok(result, "%08x\n", GetLastError());
811 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
813 dwLen = cTestData[i].enclen;
814 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
815 ok(result, "%08x\n", GetLastError());
816 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
818 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
819 ok(result, "%08x\n", GetLastError());
820 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
821 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
822 if((dwLen != cTestData[i].enclen) ||
823 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
825 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
826 printBytes("got",pbData,dwLen);
829 result = CryptDestroyKey(hKey);
830 ok(result, "%08x\n", GetLastError());
833 static void test_sha2(void)
835 static const unsigned char sha256hash[32] = {
836 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
837 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
838 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
841 static const unsigned char sha384hash[48] = {
842 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
843 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
844 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
845 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
846 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
848 static const unsigned char sha512hash[64] = {
849 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
850 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
851 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
852 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
853 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
854 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
855 0xb7, 0xf4, 0x81, 0xd4
857 unsigned char pbData[2048];
860 BYTE pbHashValue[64];
864 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
867 SetLastError(0xdeadbeef);
868 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
869 if (!result && GetLastError() == NTE_BAD_ALGID) {
870 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
873 ok(result, "%08x\n", GetLastError());
876 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
877 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
879 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
880 ok(result, "%08x\n", GetLastError());
883 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
884 ok(result, "%08x\n", GetLastError());
886 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
888 result = CryptDestroyHash(hHash);
889 ok(result, "%08x\n", GetLastError());
893 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
894 ok(result, "%08x\n", GetLastError());
897 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
898 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
900 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
901 ok(result, "%08x\n", GetLastError());
904 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
905 ok(result, "%08x\n", GetLastError());
907 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
909 result = CryptDestroyHash(hHash);
910 ok(result, "%08x\n", GetLastError());
914 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
915 ok(result, "%08x\n", GetLastError());
918 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
919 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
921 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
922 ok(result, "%08x\n", GetLastError());
925 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
926 ok(result, "%08x\n", GetLastError());
928 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
930 result = CryptDestroyHash(hHash);
931 ok(result, "%08x\n", GetLastError());
935 static void test_rc2(void)
937 static const BYTE rc2_40_encrypted[16] = {
938 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
939 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
940 static const BYTE rc2_128_encrypted[] = {
941 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
946 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
948 unsigned char pbData[2000], pbHashValue[16];
951 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
954 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
956 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
958 CRYPT_INTEGER_BLOB salt;
960 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
961 ok(result, "%08x\n", GetLastError());
964 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
965 ok(result, "%08x\n", GetLastError());
967 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
968 ok(result, "%08x\n", GetLastError());
970 dwLen = sizeof(DWORD);
971 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
972 ok(result, "%08x\n", GetLastError());
974 dwMode = CRYPT_MODE_CBC;
975 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
976 ok(result, "%08x\n", GetLastError());
978 dwLen = sizeof(DWORD);
979 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
980 ok(result, "%08x\n", GetLastError());
982 dwModeBits = 0xdeadbeef;
983 dwLen = sizeof(DWORD);
984 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
985 ok(result, "%08x\n", GetLastError());
987 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
988 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
989 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
990 " got %08x\n", dwModeBits);
992 dwLen = sizeof(DWORD);
993 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
994 ok(result, "%08x\n", GetLastError());
996 dwLen = sizeof(DWORD);
997 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
998 ok(result, "%08x\n", GetLastError());
1000 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1001 ok(result, "%08x\n", GetLastError());
1002 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1003 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1004 HeapFree(GetProcessHeap(), 0, pbTemp);
1006 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1007 ok(result, "%08x\n", GetLastError());
1008 /* The default salt length is always 11... */
1009 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1010 /* and the default salt is always empty. */
1011 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1012 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1013 for (i=0; i<dwLen; i++)
1014 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1015 HeapFree(GetProcessHeap(), 0, pbTemp);
1017 dwLen = sizeof(DWORD);
1018 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1020 result = CryptDestroyHash(hHash);
1021 ok(result, "%08x\n", GetLastError());
1024 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1025 ok(result, "%08x\n", GetLastError());
1027 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1029 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1030 ok(result, "%08x\n", GetLastError());
1031 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1032 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1033 HeapFree(GetProcessHeap(), 0, pbTemp);
1035 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1036 ok(result, "%08x\n", GetLastError());
1038 /* Setting the salt also succeeds... */
1039 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1040 ok(result, "setting salt failed: %08x\n", GetLastError());
1041 /* but the resulting salt length is now zero? */
1043 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1044 ok(result, "%08x\n", GetLastError());
1045 ok(dwLen == 0, "unexpected salt length %d\n", dwLen);
1046 /* What sizes salt can I set? */
1047 salt.pbData = pbData;
1048 for (i=0; i<24; i++)
1051 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1052 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1053 /* The returned salt length is the same as the set salt length */
1054 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1055 ok(result, "%08x\n", GetLastError());
1056 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1059 SetLastError(0xdeadbeef);
1060 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1062 broken(result), /* Win9x, WinMe, NT4, W2K */
1063 "%08x\n", GetLastError());
1065 result = CryptDestroyKey(hKey);
1066 ok(result, "%08x\n", GetLastError());
1069 /* Again, but test setting the effective key len */
1070 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1072 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1074 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1076 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1077 ok(result, "%08x\n", GetLastError());
1080 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1081 ok(result, "%08x\n", GetLastError());
1083 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1084 ok(result, "%08x\n", GetLastError());
1086 SetLastError(0xdeadbeef);
1087 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1088 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1090 SetLastError(0xdeadbeef);
1091 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1092 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1094 SetLastError(0xdeadbeef);
1095 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1097 dwLen = sizeof(dwKeyLen);
1098 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1099 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1100 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1101 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1104 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1105 ok(result, "%d\n", GetLastError());
1107 dwLen = sizeof(dwKeyLen);
1108 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1109 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1110 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1111 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1113 result = CryptDestroyHash(hHash);
1114 ok(result, "%08x\n", GetLastError());
1117 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1118 ok(result, "%08x\n", GetLastError());
1120 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1121 "RC2 encryption failed!\n");
1123 /* Oddly enough this succeeds, though it should have no effect */
1125 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1126 ok(result, "%d\n", GetLastError());
1128 result = CryptDestroyKey(hKey);
1129 ok(result, "%08x\n", GetLastError());
1133 static void test_rc4(void)
1135 static const BYTE rc4[16] = {
1136 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1137 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1141 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1142 unsigned char pbData[2000], *pbTemp;
1143 unsigned char pszBuffer[256];
1146 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1149 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1151 /* rsaenh compiled without OpenSSL */
1152 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1154 CRYPT_INTEGER_BLOB salt;
1156 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1157 ok(result, "%08x\n", GetLastError());
1160 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1161 ok(result, "%08x\n", GetLastError());
1163 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1164 ok(result, "%08x\n", GetLastError());
1166 dwLen = sizeof(DWORD);
1167 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1168 ok(result, "%08x\n", GetLastError());
1170 dwLen = sizeof(DWORD);
1171 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1172 ok(result, "%08x\n", GetLastError());
1174 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1175 ok(result, "%08x\n", GetLastError());
1176 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1177 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1178 HeapFree(GetProcessHeap(), 0, pbTemp);
1180 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1181 ok(result, "%08x\n", GetLastError());
1182 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1183 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1184 HeapFree(GetProcessHeap(), 0, pbTemp);
1186 dwLen = sizeof(DWORD);
1187 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1189 result = CryptDestroyHash(hHash);
1190 ok(result, "%08x\n", GetLastError());
1193 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1194 ok(result, "%08x\n", GetLastError());
1196 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1197 ok(result, "%08x\n", GetLastError());
1199 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1201 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1202 ok(result, "%08x\n", GetLastError());
1204 /* Setting the salt also succeeds... */
1205 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1206 ok(result, "setting salt failed: %08x\n", GetLastError());
1207 /* but the resulting salt length is now zero? */
1209 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1210 ok(result, "%08x\n", GetLastError());
1211 ok(dwLen == 0, "unexpected salt length %d\n", dwLen);
1212 /* What sizes salt can I set? */
1213 salt.pbData = pbData;
1214 for (i=0; i<24; i++)
1217 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1218 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1219 /* The returned salt length is the same as the set salt length */
1220 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1221 ok(result, "%08x\n", GetLastError());
1222 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1225 SetLastError(0xdeadbeef);
1226 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1228 broken(result), /* Win9x, WinMe, NT4, W2K */
1229 "%08x\n", GetLastError());
1231 result = CryptDestroyKey(hKey);
1232 ok(result, "%08x\n", GetLastError());
1236 static void test_hmac(void) {
1240 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1241 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1244 static const BYTE hmac[16] = {
1245 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1246 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1249 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1251 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1253 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1254 ok(result, "%08x\n", GetLastError());
1255 if (!result) return;
1257 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1258 ok(result, "%08x\n", GetLastError());
1260 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1261 ok(result, "%08x\n", GetLastError());
1263 dwLen = sizeof(abData)/sizeof(BYTE);
1264 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1265 ok(result, "%08x\n", GetLastError());
1267 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1269 result = CryptDestroyHash(hHash);
1270 ok(result, "%08x\n", GetLastError());
1272 result = CryptDestroyKey(hKey);
1273 ok(result, "%08x\n", GetLastError());
1275 /* Provoke errors */
1276 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1277 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1280 static void test_mac(void) {
1285 BYTE abData[256], abEnc[264];
1286 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1289 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1290 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1292 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1295 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1296 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1298 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1299 ok(result, "%08x\n", GetLastError());
1300 if (!result) return;
1302 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1303 ok(result, "%08x\n", GetLastError());
1305 dwLen = sizeof(abData)/sizeof(BYTE);
1306 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1307 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1309 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1311 result = CryptDestroyHash(hHash);
1312 ok(result, "%08x\n", GetLastError());
1314 result = CryptDestroyKey(hKey);
1315 ok(result, "%08x\n", GetLastError());
1317 /* Provoke errors */
1318 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1320 SetLastError(0xdeadbeef);
1321 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1322 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1323 broken(result), /* Win9x, WinMe, NT4, W2K */
1324 "%08x\n", GetLastError());
1326 result = CryptDestroyKey(hKey);
1327 ok(result, "%08x\n", GetLastError());
1330 static BYTE abPlainPrivateKey[596] = {
1331 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1332 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1333 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1334 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1335 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1336 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1337 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1338 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1339 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1340 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1341 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1342 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1343 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1344 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1345 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1346 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1347 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1348 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1349 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1350 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1351 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1352 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1353 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1354 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1355 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1356 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1357 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1358 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1359 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1360 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1361 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1362 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1363 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1364 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1365 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1366 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1367 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1368 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1369 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1370 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1371 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1372 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1373 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1374 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1375 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1376 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1377 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1378 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1379 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1380 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1381 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1382 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1383 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1384 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1385 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1386 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1387 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1388 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1389 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1390 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1391 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1392 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1393 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1394 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1395 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1396 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1397 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1398 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1399 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1400 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1401 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1402 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1403 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1404 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1405 0xf2, 0x5d, 0x58, 0x07
1408 static void test_import_private(void)
1411 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1413 static BYTE abSessionKey[148] = {
1414 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1415 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1416 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1417 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1418 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1419 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1420 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1421 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1422 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1423 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1424 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1425 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1426 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1427 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1428 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1429 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1430 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1431 0x04, 0x8c, 0x49, 0x92
1433 static BYTE abEncryptedMessage[12] = {
1434 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1435 0x1c, 0xfd, 0xde, 0x71
1438 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1439 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1441 /* rsaenh compiled without OpenSSL */
1442 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1446 dwLen = (DWORD)sizeof(abSessionKey);
1447 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1448 ok(result, "%08x\n", GetLastError());
1449 if (!result) return;
1452 dwLen = sizeof(DWORD);
1453 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1454 ok(result, "%08x\n", GetLastError());
1456 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1457 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1458 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1459 " got %08x\n", dwVal);
1461 dwLen = (DWORD)sizeof(abEncryptedMessage);
1462 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1463 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1464 "%08x, len: %d\n", GetLastError(), dwLen);
1465 CryptDestroyKey(hSessionKey);
1467 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1469 dwLen = (DWORD)sizeof(abSessionKey);
1470 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1471 ok(result, "%08x\n", GetLastError());
1472 CryptDestroyKey(hSessionKey);
1473 if (!result) return;
1475 dwLen = (DWORD)sizeof(abSessionKey);
1476 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1477 ok(result, "%08x\n", GetLastError());
1478 if (!result) return;
1480 CryptDestroyKey(hSessionKey);
1481 CryptDestroyKey(hKeyExchangeKey);
1484 static void test_verify_signature(void) {
1486 HCRYPTKEY hPubSignKey;
1487 BYTE abData[] = "Wine rocks!";
1489 BYTE abPubKey[148] = {
1490 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1491 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1492 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1493 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1494 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1495 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1496 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1497 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1498 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1499 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1500 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1501 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1502 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1503 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1504 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1505 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1506 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1507 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1508 0xe1, 0x21, 0x50, 0xac
1510 /* md2 with hash oid */
1511 BYTE abSignatureMD2[128] = {
1512 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1513 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1514 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1515 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1516 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1517 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1518 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1519 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1520 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1521 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1522 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1523 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1524 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1525 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1526 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1527 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1529 /* md2 without hash oid */
1530 BYTE abSignatureMD2NoOID[128] = {
1531 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1532 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1533 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1534 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1535 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1536 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1537 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1538 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1539 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1540 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1541 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1542 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1543 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1544 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1545 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1546 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1548 /* md4 with hash oid */
1549 BYTE abSignatureMD4[128] = {
1550 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1551 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1552 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1553 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1554 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1555 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1556 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1557 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1558 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1559 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1560 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1561 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1562 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1563 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1564 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1565 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1567 /* md4 without hash oid */
1568 BYTE abSignatureMD4NoOID[128] = {
1569 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1570 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1571 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1572 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1573 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1574 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1575 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1576 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1577 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1578 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1579 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1580 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1581 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1582 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1583 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1584 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1586 /* md5 with hash oid */
1587 BYTE abSignatureMD5[128] = {
1588 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1589 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1590 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1591 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1592 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1593 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1594 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1595 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1596 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1597 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1598 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1599 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1600 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1601 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1602 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1603 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1605 /* md5 without hash oid */
1606 BYTE abSignatureMD5NoOID[128] = {
1607 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1608 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1609 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1610 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1611 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1612 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1613 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1614 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1615 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1616 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1617 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1618 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1619 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1620 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1621 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1622 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1624 /* sha with hash oid */
1625 BYTE abSignatureSHA[128] = {
1626 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1627 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1628 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1629 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1630 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1631 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1632 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1633 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1634 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1635 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1636 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1637 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1638 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1639 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1640 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1641 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1643 /* sha without hash oid */
1644 BYTE abSignatureSHANoOID[128] = {
1645 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1646 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1647 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1648 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1649 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1650 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1651 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1652 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1653 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1654 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1655 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1656 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1657 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1658 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1659 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1660 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1663 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1664 ok(result, "%08x\n", GetLastError());
1665 if (!result) return;
1667 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1668 ok(result, "%08x\n", GetLastError());
1669 if (!result) return;
1671 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1672 ok(result, "%08x\n", GetLastError());
1673 if (!result) return;
1675 /*check that a NULL pointer signature is correctly handled*/
1676 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1677 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1678 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1681 /* check that we get a bad signature error when the signature is too short*/
1682 SetLastError(0xdeadbeef);
1683 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1684 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1685 broken(result), /* Win9x, WinMe, NT4 */
1686 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1688 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1689 ok(result, "%08x\n", GetLastError());
1690 if (!result) return;
1692 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1693 ok(result, "%08x\n", GetLastError());
1694 if (!result) return;
1696 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1697 * the OID at all. */
1698 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1699 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1700 if (result) return;*/
1702 CryptDestroyHash(hHash);
1704 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1705 ok(result, "%08x\n", GetLastError());
1706 if (!result) return;
1708 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1709 ok(result, "%08x\n", GetLastError());
1710 if (!result) return;
1712 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1713 ok(result, "%08x\n", GetLastError());
1714 if (!result) return;
1716 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1717 ok(result, "%08x\n", GetLastError());
1718 if (!result) return;
1720 CryptDestroyHash(hHash);
1722 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1723 ok(result, "%08x\n", GetLastError());
1724 if (!result) return;
1726 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1727 ok(result, "%08x\n", GetLastError());
1728 if (!result) return;
1730 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1731 ok(result, "%08x\n", GetLastError());
1732 if (!result) return;
1734 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1735 ok(result, "%08x\n", GetLastError());
1736 if (!result) return;
1738 CryptDestroyHash(hHash);
1740 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1741 ok(result, "%08x\n", GetLastError());
1742 if (!result) return;
1744 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1745 ok(result, "%08x\n", GetLastError());
1746 if (!result) return;
1748 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1749 ok(result, "%08x\n", GetLastError());
1750 if (!result) return;
1752 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1753 ok(result, "%08x\n", GetLastError());
1754 if (!result) return;
1756 CryptDestroyHash(hHash);
1757 CryptDestroyKey(hPubSignKey);
1760 static void test_rsa_encrypt(void)
1763 BYTE abData[2048] = "Wine rocks!";
1767 /* It is allowed to use the key exchange key for encryption/decryption */
1768 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1769 ok (result, "%08x\n", GetLastError());
1770 if (!result) return;
1773 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1774 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1775 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1777 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1778 ok (result, "%08x\n", GetLastError());
1779 if (!result) return;
1781 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1782 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1785 dwLen = sizeof(DWORD);
1786 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1787 ok(result, "%08x\n", GetLastError());
1789 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1790 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1791 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1792 " got %08x\n", dwVal);
1794 /* An RSA key doesn't support salt */
1795 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1796 ok(!result && GetLastError() == NTE_BAD_KEY,
1797 "expected NTE_BAD_KEY, got %08x\n", GetLastError());
1799 /* The key exchange key's public key may be exported.. */
1800 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1801 ok(result, "%08x\n", GetLastError());
1802 /* but its private key may not be. */
1803 SetLastError(0xdeadbeef);
1804 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1805 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1806 broken(result), /* Win9x/NT4 */
1807 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1808 /* Setting the permissions of the key exchange key isn't allowed, either. */
1809 dwVal |= CRYPT_EXPORT;
1810 SetLastError(0xdeadbeef);
1811 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1813 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1814 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1816 CryptDestroyKey(hRSAKey);
1818 /* It is not allowed to use the signature key for encryption/decryption */
1819 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1820 ok (result, "%08x\n", GetLastError());
1821 if (!result) return;
1824 dwLen = sizeof(DWORD);
1825 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1826 ok(result, "%08x\n", GetLastError());
1828 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1829 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1830 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1831 " got %08x\n", dwVal);
1833 /* The signature key's public key may also be exported.. */
1834 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1835 ok(result, "%08x\n", GetLastError());
1836 /* but its private key may not be. */
1837 SetLastError(0xdeadbeef);
1838 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1839 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1840 broken(result), /* Win9x/NT4 */
1841 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1842 /* Setting the permissions of the signature key isn't allowed, either. */
1843 dwVal |= CRYPT_EXPORT;
1844 SetLastError(0xdeadbeef);
1845 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1847 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1848 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1851 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1852 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1854 CryptDestroyKey(hRSAKey);
1857 static void test_import_export(void)
1859 DWORD dwLen, dwDataLen, dwVal;
1860 HCRYPTKEY hPublicKey, hPrivKey;
1863 BYTE emptyKey[2048], *exported_key;
1864 static BYTE abPlainPublicKey[84] = {
1865 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1866 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1867 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1868 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1869 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1870 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1871 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1872 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1873 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1874 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1875 0x11, 0x11, 0x11, 0x11
1877 static BYTE priv_key_with_high_bit[] = {
1878 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1879 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1880 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1881 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1882 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1883 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1884 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1885 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1886 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1887 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1888 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1889 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1890 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1891 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1892 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1893 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1894 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1895 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1896 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1897 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1898 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1899 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1900 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1901 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1902 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1903 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1904 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1905 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1906 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1907 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1908 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1909 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1910 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1911 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1912 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1913 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1914 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1915 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1916 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1917 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1918 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1919 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1920 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1921 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1922 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1923 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1924 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1925 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1926 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1927 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1928 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1929 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1930 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1931 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1932 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1933 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1934 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1935 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1936 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1937 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1938 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1939 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1940 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1941 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1942 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1943 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1944 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1945 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1946 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1947 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1948 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1949 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1950 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1951 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1952 0xb6, 0x5f, 0x01, 0x5e
1954 static const BYTE expected_exported_priv_key[] = {
1955 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1956 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1957 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1958 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1959 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1960 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1961 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1962 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1963 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1964 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1965 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1966 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1967 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1968 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1969 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1970 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1971 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1972 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1973 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1974 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1975 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1976 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1977 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1978 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1979 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1980 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1981 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1982 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1983 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1984 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1985 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1986 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1987 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1988 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1989 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1990 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1991 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1992 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1993 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1994 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1995 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1996 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1997 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1998 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1999 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2000 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2001 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2002 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2003 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2004 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2005 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2006 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2007 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2008 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2009 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2010 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2011 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2012 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2013 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2014 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2015 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2016 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2017 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2018 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2019 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2020 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2021 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2022 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2023 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2024 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2025 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2026 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2027 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2028 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2029 0xb6, 0x5f, 0x01, 0x5e
2033 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2034 ok(result, "failed to import the public key\n");
2036 dwDataLen=sizeof(algID);
2037 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2038 ok(result, "failed to get the KP_ALGID from the imported public key\n");
2039 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2042 dwDataLen = sizeof(DWORD);
2043 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2044 ok(result, "%08x\n", GetLastError());
2046 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2047 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2048 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2049 " got %08x\n", dwVal);
2050 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2051 ok(result, "failed to export the fresh imported public key\n");
2052 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2053 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2055 CryptDestroyKey(hPublicKey);
2057 result = CryptImportKey(hProv, priv_key_with_high_bit,
2058 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2059 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2061 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2062 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2063 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2064 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2066 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2068 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2070 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2071 "unexpected value\n");
2073 HeapFree(GetProcessHeap(), 0, exported_key);
2075 CryptDestroyKey(hPrivKey);
2078 static void test_schannel_provider(void)
2081 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2082 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2085 SCHANNEL_ALG saSChannelAlg;
2086 CRYPT_DATA_BLOB data_blob;
2087 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2088 BYTE abTLS1Master[140] = {
2089 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2090 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2091 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2092 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2093 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2094 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2095 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2096 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2097 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2098 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2099 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2100 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2101 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2102 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2103 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2104 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2105 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2106 0xd3, 0x1e, 0x82, 0xb3
2108 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2109 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2110 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2111 BYTE abClientFinished[16] = "client finished";
2112 BYTE abData[16] = "Wine rocks!";
2114 static const BYTE abEncryptedData[16] = {
2115 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2116 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2118 static const BYTE abPRF[16] = {
2119 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2120 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2122 static const BYTE abMD5[16] = {
2123 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2124 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2127 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2130 win_skip("no PROV_RSA_SCHANNEL support\n");
2133 ok (result, "%08x\n", GetLastError());
2135 CryptReleaseContext(hProv, 0);
2137 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2138 ok (result, "%08x\n", GetLastError());
2139 if (!result) return;
2141 /* To get deterministic results, we import the TLS1 master secret (which
2142 * is typically generated from a random generator). Therefore, we need
2144 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2145 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2146 ok (result, "%08x\n", GetLastError());
2147 if (!result) return;
2149 dwLen = (DWORD)sizeof(abTLS1Master);
2150 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2151 ok (result, "%08x\n", GetLastError());
2152 if (!result) return;
2154 /* Setting the TLS1 client and server random parameters, as well as the
2155 * MAC and encryption algorithm parameters. */
2156 data_blob.cbData = 33;
2157 data_blob.pbData = abClientSecret;
2158 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2159 ok (result, "%08x\n", GetLastError());
2160 if (!result) return;
2162 data_blob.cbData = 33;
2163 data_blob.pbData = abServerSecret;
2164 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2165 ok (result, "%08x\n", GetLastError());
2166 if (!result) return;
2168 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2169 saSChannelAlg.Algid = CALG_DES;
2170 saSChannelAlg.cBits = 64;
2171 saSChannelAlg.dwFlags = 0;
2172 saSChannelAlg.dwReserved = 0;
2173 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2174 ok (result, "%08x\n", GetLastError());
2175 if (!result) return;
2177 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2178 saSChannelAlg.Algid = CALG_MD5;
2179 saSChannelAlg.cBits = 128;
2180 saSChannelAlg.dwFlags = 0;
2181 saSChannelAlg.dwReserved = 0;
2182 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2183 ok (result, "%08x\n", GetLastError());
2184 if (!result) return;
2186 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2187 * (Keys can only be derived from hashes, not from other keys.) */
2188 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2189 ok (result, "%08x\n", GetLastError());
2190 if (!result) return;
2192 /* Deriving the server write encryption key from the master hash */
2193 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2194 ok (result, "%08x\n", GetLastError());
2195 if (!result) return;
2197 /* Encrypting some data with the server write encryption key and checking the result. */
2199 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2200 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2202 /* Second test case: Test the TLS1 pseudo random number function. */
2203 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2204 ok (result, "%08x\n", GetLastError());
2205 if (!result) return;
2207 /* Set the label and seed parameters for the random number function */
2208 data_blob.cbData = 36;
2209 data_blob.pbData = abHashedHandshakes;
2210 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2211 ok (result, "%08x\n", GetLastError());
2212 if (!result) return;
2214 data_blob.cbData = 15;
2215 data_blob.pbData = abClientFinished;
2216 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2217 ok (result, "%08x\n", GetLastError());
2218 if (!result) return;
2220 /* Generate some pseudo random bytes and check if they are correct. */
2221 dwLen = (DWORD)sizeof(abData);
2222 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2223 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2224 "%08x\n", GetLastError());
2226 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2227 * Hash some data with the HMAC. Compare results. */
2228 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2229 ok (result, "%08x\n", GetLastError());
2230 if (!result) return;
2232 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2233 ok (result, "%08x\n", GetLastError());
2234 if (!result) return;
2236 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2237 ok (result, "%08x\n", GetLastError());
2238 if (!result) return;
2240 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2241 ok (result, "%08x\n", GetLastError());
2242 if (!result) return;
2244 dwLen = (DWORD)sizeof(abMD5Hash);
2245 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2246 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2248 CryptDestroyHash(hHMAC);
2249 CryptDestroyHash(hTLS1PRF);
2250 CryptDestroyHash(hMasterHash);
2251 CryptDestroyKey(hServerWriteMACKey);
2252 CryptDestroyKey(hServerWriteKey);
2253 CryptDestroyKey(hRSAKey);
2254 CryptDestroyKey(hMasterSecret);
2255 CryptReleaseContext(hProv, 0);
2256 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2259 /* Test that a key can be used to encrypt data and exported, and that, when
2260 * the exported key is imported again, can be used to decrypt the original
2263 static void test_rsa_round_trip(void)
2265 static const char test_string[] = "Well this is a fine how-do-you-do.";
2267 HCRYPTKEY signKey, keyExchangeKey;
2269 BYTE data[256], *exportedKey;
2270 DWORD dataLen, keyLen;
2272 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2273 CRYPT_DELETEKEYSET);
2275 /* Generate a new key... */
2276 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2278 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2279 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2280 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2281 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2282 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2283 /* encrypt some data with it... */
2284 memcpy(data, test_string, strlen(test_string) + 1);
2285 dataLen = strlen(test_string) + 1;
2286 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2288 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2289 "CryptEncrypt failed: %08x\n", GetLastError());
2290 /* export the key... */
2291 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2293 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2294 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2295 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2297 /* destroy the key... */
2298 CryptDestroyKey(keyExchangeKey);
2299 CryptDestroyKey(signKey);
2300 /* import the key again... */
2301 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2302 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2303 HeapFree(GetProcessHeap(), 0, exportedKey);
2304 /* and decrypt the data encrypted with the original key with the imported
2307 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2308 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2309 "CryptDecrypt failed: %08x\n", GetLastError());
2312 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2313 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2315 CryptDestroyKey(keyExchangeKey);
2316 CryptReleaseContext(prov, 0);
2318 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2319 CRYPT_DELETEKEYSET);
2322 static void test_enum_container(void)
2324 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2326 BOOL result, fFound = FALSE;
2328 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2329 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2330 SetLastError(0xdeadbeef);
2331 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2332 ok (result, "%08x\n", GetLastError());
2333 ok (dwBufferLen == MAX_PATH + 1 ||
2334 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2335 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2337 /* If the result fits into abContainerName dwBufferLen is left untouched */
2338 dwBufferLen = (DWORD)sizeof(abContainerName);
2339 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2340 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2342 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2344 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2345 dwBufferLen = (DWORD)sizeof(abContainerName);
2346 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2348 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2351 static BYTE signBlob[] = {
2352 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2353 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2354 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2355 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2356 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2357 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2358 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2359 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2360 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2361 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2362 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2363 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2364 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2365 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2366 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2367 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2368 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2369 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2370 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2371 0xb6,0x85,0x86,0x07 };
2373 static void test_null_provider(void)
2378 DWORD keySpec, dataLen,dwParam;
2379 char szName[MAX_PATH];
2381 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2382 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2383 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2384 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2385 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2386 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2387 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2388 CRYPT_DELETEKEYSET);
2389 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2390 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2391 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2392 CRYPT_DELETEKEYSET);
2393 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2394 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2395 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2396 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2397 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2399 /* Delete the default container. */
2400 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2401 /* Once you've deleted the default container you can't open it as if it
2404 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2405 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2406 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2407 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2408 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2409 CRYPT_VERIFYCONTEXT);
2410 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2411 if (!result) return;
2412 dataLen = sizeof(keySpec);
2413 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2415 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2416 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2417 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2418 * supported, you can't get the keys from this container.
2420 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2421 ok(!result && GetLastError() == NTE_NO_KEY,
2422 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2423 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2424 ok(!result && GetLastError() == NTE_NO_KEY,
2425 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2426 result = CryptReleaseContext(prov, 0);
2427 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2428 /* You can create a new default container. */
2429 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2431 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2432 /* But you still can't get the keys (until one's been generated.) */
2433 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2434 ok(!result && GetLastError() == NTE_NO_KEY,
2435 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2436 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2437 ok(!result && GetLastError() == NTE_NO_KEY,
2438 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2439 CryptReleaseContext(prov, 0);
2440 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2442 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2443 CRYPT_DELETEKEYSET);
2444 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2445 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2446 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2447 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2448 CRYPT_VERIFYCONTEXT);
2449 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2450 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2451 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2453 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2454 if (!result) return;
2455 /* Test provider parameters getter */
2456 dataLen = sizeof(dwParam);
2457 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2458 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2459 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2460 dataLen = sizeof(dwParam);
2461 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2462 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2463 "Expected 0, got 0x%08X\n",dwParam);
2464 dataLen = sizeof(dwParam);
2465 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2466 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2467 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2468 dataLen = sizeof(keySpec);
2469 SetLastError(0xdeadbeef);
2470 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2471 if (!result && GetLastError() == NTE_BAD_TYPE)
2472 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2474 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2475 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2476 /* PP_CONTAINER parameter */
2477 dataLen = sizeof(szName);
2478 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2479 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2480 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2481 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2482 /* PP_UNIQUE_CONTAINER parameter */
2483 dataLen = sizeof(szName);
2484 SetLastError(0xdeadbeef);
2485 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2486 if (!result && GetLastError() == NTE_BAD_TYPE)
2488 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2492 char container[MAX_PATH];
2494 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2495 uniquecontainer(container);
2498 ok(dataLen == strlen(container)+1 ||
2499 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2500 "Expected a param length of 70, got %d\n", dataLen);
2501 ok(!strcmp(container, szName) ||
2502 broken(!strcmp(szName, szContainer)) /* WinME */,
2503 "Wrong container name : %s\n", szName);
2506 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2507 ok(!result && GetLastError() == NTE_NO_KEY,
2508 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2509 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2510 ok(!result && GetLastError() == NTE_NO_KEY,
2511 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2513 /* Importing a key exchange blob.. */
2514 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2516 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2517 CryptDestroyKey(key);
2518 /* allows access to the key exchange key.. */
2519 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2520 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2521 CryptDestroyKey(key);
2522 /* but not to the private key. */
2523 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2524 ok(!result && GetLastError() == NTE_NO_KEY,
2525 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2526 CryptReleaseContext(prov, 0);
2527 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2528 CRYPT_DELETEKEYSET);
2530 /* Whereas importing a sign blob.. */
2531 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2533 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2534 if (!result) return;
2535 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2536 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2537 CryptDestroyKey(key);
2538 /* doesn't allow access to the key exchange key.. */
2539 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2540 ok(!result && GetLastError() == NTE_NO_KEY,
2541 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2542 /* but does to the private key. */
2543 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2544 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2545 CryptDestroyKey(key);
2546 CryptReleaseContext(prov, 0);
2548 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2549 CRYPT_DELETEKEYSET);
2551 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2552 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2554 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2555 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2556 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2557 CryptDestroyKey(key);
2558 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2559 ok(!result, "expected CryptGetUserKey to fail\n");
2560 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2561 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2562 CryptDestroyKey(key);
2563 CryptReleaseContext(prov, 0);
2565 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2566 CRYPT_DELETEKEYSET);
2568 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2569 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2571 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2572 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2573 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2574 CryptDestroyKey(key);
2575 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2576 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2577 CryptDestroyKey(key);
2578 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2579 ok(!result, "expected CryptGetUserKey to fail\n");
2580 CryptReleaseContext(prov, 0);
2582 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2583 CRYPT_DELETEKEYSET);
2585 /* test for the bug in accessing the user key in a container
2587 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2589 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2590 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2591 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2592 CryptDestroyKey(key);
2593 CryptReleaseContext(prov,0);
2594 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2595 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2596 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2597 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2598 CryptDestroyKey(key);
2599 CryptReleaseContext(prov, 0);
2601 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2602 CRYPT_DELETEKEYSET);
2604 /* test the machine key set */
2605 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2606 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2607 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2608 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2609 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2610 CryptReleaseContext(prov, 0);
2611 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2612 CRYPT_MACHINE_KEYSET);
2613 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2614 CryptReleaseContext(prov,0);
2615 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2616 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2617 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2619 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2620 CRYPT_MACHINE_KEYSET);
2621 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2622 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2626 static void test_key_permissions(void)
2628 HCRYPTKEY hKey1, hKey2;
2632 /* Create keys that are exportable */
2633 if (!init_base_environment(CRYPT_EXPORTABLE))
2636 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2637 ok (result, "%08x\n", GetLastError());
2638 if (!result) return;
2641 dwLen = sizeof(DWORD);
2642 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2643 ok(result, "%08x\n", GetLastError());
2645 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2646 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2647 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2648 " got %08x\n", dwVal);
2650 /* The key exchange key's public key may be exported.. */
2651 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2652 ok(result, "%08x\n", GetLastError());
2653 /* and its private key may be too. */
2654 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2655 ok(result, "%08x\n", GetLastError());
2656 /* Turning off the key's export permissions is "allowed".. */
2657 dwVal &= ~CRYPT_EXPORT;
2658 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2660 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2661 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2662 "%08x\n", GetLastError());
2663 /* but it has no effect. */
2665 dwLen = sizeof(DWORD);
2666 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2667 ok(result, "%08x\n", GetLastError());
2669 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2670 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2671 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2672 " got %08x\n", dwVal);
2673 /* Thus, changing the export flag of the key doesn't affect whether the key
2676 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2677 ok(result, "%08x\n", GetLastError());
2679 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2680 ok (result, "%08x\n", GetLastError());
2682 /* A subsequent get of the same key, into a different handle, also doesn't
2683 * show that the permissions have been changed.
2686 dwLen = sizeof(DWORD);
2687 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2688 ok(result, "%08x\n", GetLastError());
2690 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2691 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2692 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2693 " got %08x\n", dwVal);
2695 CryptDestroyKey(hKey2);
2696 CryptDestroyKey(hKey1);
2698 clean_up_base_environment();
2701 static void test_key_initialization(void)
2704 HCRYPTPROV prov1, prov2;
2705 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2707 static BYTE abSessionKey[148] = {
2708 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2709 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2710 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2711 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2712 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2713 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2714 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2715 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2716 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2717 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2718 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2719 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2720 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2721 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2722 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2723 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2724 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2725 0x04, 0x8c, 0x49, 0x92
2728 /* Like init_base_environment, but doesn't generate new keys, as they'll
2729 * be imported instead.
2731 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2733 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2735 ok(result, "%08x\n", GetLastError());
2737 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2738 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2740 dwLen = (DWORD)sizeof(abSessionKey);
2741 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2742 ok(result, "%08x\n", GetLastError());
2744 /* Once the key has been imported, subsequently acquiring a context with
2745 * the same name will allow retrieving the key.
2747 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2748 ok(result, "%08x\n", GetLastError());
2749 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2750 ok(result, "%08x\n", GetLastError());
2751 if (result) CryptDestroyKey(hKey);
2752 CryptReleaseContext(prov2, 0);
2754 CryptDestroyKey(hSessionKey);
2755 CryptDestroyKey(hKeyExchangeKey);
2756 CryptReleaseContext(prov1, 0);
2757 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2758 CRYPT_DELETEKEYSET);
2763 if (!init_base_environment(0))
2775 test_block_cipher_modes();
2776 test_import_private();
2777 test_verify_signature();
2779 test_import_export();
2780 test_enum_container();
2781 clean_up_base_environment();
2782 test_key_permissions();
2783 test_key_initialization();
2784 test_schannel_provider();
2785 test_null_provider();
2786 test_rsa_round_trip();
2787 if (!init_aes_environment())
2793 clean_up_aes_environment();