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 = CryptAcquireContextA(&prov, NULL, szProvider, 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, (const 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 if (!pCryptDuplicateHash)
492 win_skip("CryptDuplicateHash is not available\n");
496 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
497 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
499 result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
500 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
502 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
503 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
505 result = pCryptDuplicateHash(hHash, NULL, 0, &hHashClone);
506 ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
509 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
510 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
512 /* add data after duplicating the hash */
513 result = CryptHashData(hHash, (const BYTE *)"more data", sizeof("more data"), 0);
514 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
516 result = CryptDestroyHash(hHash);
517 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
519 result = CryptDestroyHash(hHashClone);
520 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
522 result = CryptReleaseContext(prov, 0);
523 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
526 static void test_block_cipher_modes(void)
528 static const BYTE plain[23] = {
529 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
530 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
531 static const BYTE ecb[24] = {
532 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
533 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
534 static const BYTE cbc[24] = {
535 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
536 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
537 static const BYTE cfb[24] = {
538 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
539 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
545 result = derive_key(CALG_RC2, &hKey, 40);
548 memcpy(abData, plain, sizeof(plain));
550 dwMode = CRYPT_MODE_ECB;
551 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
552 ok(result, "%08x\n", GetLastError());
554 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
555 ok(result, "%08x\n", GetLastError());
556 ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
559 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
560 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
561 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
563 SetLastError(ERROR_SUCCESS);
565 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
566 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
567 "%08x, dwLen: %d\n", GetLastError(), dwLen);
569 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
570 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
571 "%08x, dwLen: %d\n", GetLastError(), dwLen);
573 dwMode = CRYPT_MODE_CBC;
574 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
575 ok(result, "%08x\n", GetLastError());
578 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
579 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
580 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
583 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
584 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
585 "%08x, dwLen: %d\n", GetLastError(), dwLen);
587 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
588 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
589 "%08x, dwLen: %d\n", GetLastError(), dwLen);
591 dwMode = CRYPT_MODE_CFB;
592 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
593 ok(result, "%08x\n", GetLastError());
596 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
597 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
600 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
601 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
602 "%08x, dwLen: %d\n", GetLastError(), dwLen);
605 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
606 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
609 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
610 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
611 "%08x, dwLen: %d\n", GetLastError(), dwLen);
613 dwMode = CRYPT_MODE_OFB;
614 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
615 ok(result, "%08x\n", GetLastError());
618 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
619 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
621 CryptDestroyKey(hKey);
624 static void test_3des112(void)
629 unsigned char pbData[16];
632 result = derive_key(CALG_3DES_112, &hKey, 0);
634 /* rsaenh compiled without OpenSSL */
635 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
639 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
642 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
643 ok(result, "%08x\n", GetLastError());
645 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
646 ok(result, "%08x\n", GetLastError());
650 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
652 dwLen = cTestData[i].enclen;
653 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
654 ok(result, "%08x\n", GetLastError());
655 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
657 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
658 ok(result, "%08x\n", GetLastError());
659 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
660 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
661 if((dwLen != cTestData[i].enclen) ||
662 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
664 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
665 printBytes("got",pbData,dwLen);
668 result = CryptDestroyKey(hKey);
669 ok(result, "%08x\n", GetLastError());
672 static void test_des(void)
677 unsigned char pbData[16];
680 result = derive_key(CALG_DES, &hKey, 56);
682 /* rsaenh compiled without OpenSSL */
683 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
687 dwMode = CRYPT_MODE_ECB;
688 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
689 ok(result, "%08x\n", GetLastError());
691 dwLen = sizeof(DWORD);
692 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
693 ok(result, "%08x\n", GetLastError());
695 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
698 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
699 ok(result, "%08x\n", GetLastError());
701 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
702 ok(result, "%08x\n", GetLastError());
706 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
708 dwLen = cTestData[i].enclen;
709 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
710 ok(result, "%08x\n", GetLastError());
711 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
713 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
714 ok(result, "%08x\n", GetLastError());
715 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
716 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
717 if((dwLen != cTestData[i].enclen) ||
718 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
720 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
721 printBytes("got",pbData,dwLen);
725 result = CryptDestroyKey(hKey);
726 ok(result, "%08x\n", GetLastError());
729 static void test_3des(void)
734 unsigned char pbData[16];
735 static const BYTE des3[16] = {
736 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
737 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
740 result = derive_key(CALG_3DES, &hKey, 0);
743 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
746 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
747 ok(result, "%08x\n", GetLastError());
749 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
751 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
752 ok(result, "%08x\n", GetLastError());
756 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
758 dwLen = cTestData[i].enclen;
759 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
760 ok(result, "%08x\n", GetLastError());
761 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
763 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
764 ok(result, "%08x\n", GetLastError());
765 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
766 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
767 if((dwLen != cTestData[i].enclen) ||
768 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
770 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
771 printBytes("got",pbData,dwLen);
774 result = CryptDestroyKey(hKey);
775 ok(result, "%08x\n", GetLastError());
778 static void test_aes(int keylen)
783 unsigned char pbData[16];
789 result = derive_key(CALG_AES_256, &hKey, 0);
792 result = derive_key(CALG_AES_192, &hKey, 0);
796 result = derive_key(CALG_AES_128, &hKey, 0);
801 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
803 /* AES provider doesn't support salt */
804 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
805 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == ERROR_NO_TOKEN /* Win7 */),
806 "expected NTE_BAD_KEY or ERROR_NO_TOKEN, got %08x\n", GetLastError());
809 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
810 ok(result, "%08x\n", GetLastError());
812 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
813 ok(result, "%08x\n", GetLastError());
817 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
819 dwLen = cTestData[i].enclen;
820 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
821 ok(result, "%08x\n", GetLastError());
822 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
824 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
825 ok(result, "%08x\n", GetLastError());
826 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
827 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
828 if((dwLen != cTestData[i].enclen) ||
829 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
831 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
832 printBytes("got",pbData,dwLen);
835 result = CryptDestroyKey(hKey);
836 ok(result, "%08x\n", GetLastError());
839 static void test_sha2(void)
841 static const unsigned char sha256hash[32] = {
842 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
843 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
844 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
847 static const unsigned char sha384hash[48] = {
848 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
849 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
850 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
851 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
852 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
854 static const unsigned char sha512hash[64] = {
855 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
856 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
857 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
858 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
859 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
860 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
861 0xb7, 0xf4, 0x81, 0xd4
863 unsigned char pbData[2048];
866 BYTE pbHashValue[64];
870 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
873 SetLastError(0xdeadbeef);
874 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
875 if (!result && GetLastError() == NTE_BAD_ALGID) {
876 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
879 ok(result, "%08x\n", GetLastError());
882 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
883 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
885 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
886 ok(result, "%08x\n", GetLastError());
889 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
890 ok(result, "%08x\n", GetLastError());
892 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
894 result = CryptDestroyHash(hHash);
895 ok(result, "%08x\n", GetLastError());
899 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
900 ok(result, "%08x\n", GetLastError());
903 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
904 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
906 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
907 ok(result, "%08x\n", GetLastError());
910 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
911 ok(result, "%08x\n", GetLastError());
913 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
915 result = CryptDestroyHash(hHash);
916 ok(result, "%08x\n", GetLastError());
920 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
921 ok(result, "%08x\n", GetLastError());
924 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
925 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
927 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
928 ok(result, "%08x\n", GetLastError());
931 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
932 ok(result, "%08x\n", GetLastError());
934 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
936 result = CryptDestroyHash(hHash);
937 ok(result, "%08x\n", GetLastError());
941 static void test_rc2(void)
943 static const BYTE rc2_40_encrypted[16] = {
944 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
945 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
946 static const BYTE rc2_128_encrypted[] = {
947 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
952 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
954 unsigned char pbData[2000], pbHashValue[16];
957 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
960 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
962 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
964 CRYPT_INTEGER_BLOB salt;
966 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
967 ok(result, "%08x\n", GetLastError());
970 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
971 ok(result, "%08x\n", GetLastError());
973 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
974 ok(result, "%08x\n", GetLastError());
976 dwLen = sizeof(DWORD);
977 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
978 ok(result, "%08x\n", GetLastError());
980 dwMode = CRYPT_MODE_CBC;
981 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
982 ok(result, "%08x\n", GetLastError());
984 dwLen = sizeof(DWORD);
985 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
986 ok(result, "%08x\n", GetLastError());
988 dwModeBits = 0xdeadbeef;
989 dwLen = sizeof(DWORD);
990 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
991 ok(result, "%08x\n", GetLastError());
993 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
994 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
995 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
996 " got %08x\n", dwModeBits);
998 dwLen = sizeof(DWORD);
999 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1000 ok(result, "%08x\n", GetLastError());
1002 dwLen = sizeof(DWORD);
1003 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1004 ok(result, "%08x\n", GetLastError());
1006 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1007 ok(result, "%08x\n", GetLastError());
1008 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1009 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1010 HeapFree(GetProcessHeap(), 0, pbTemp);
1012 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1013 ok(result, "%08x\n", GetLastError());
1014 /* The default salt length is always 11... */
1015 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1016 /* and the default salt is always empty. */
1017 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1018 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1019 for (i=0; i<dwLen; i++)
1020 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1021 HeapFree(GetProcessHeap(), 0, pbTemp);
1023 dwLen = sizeof(DWORD);
1024 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1026 result = CryptDestroyHash(hHash);
1027 ok(result, "%08x\n", GetLastError());
1030 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1031 ok(result, "%08x\n", GetLastError());
1033 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1035 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1036 ok(result, "%08x\n", GetLastError());
1037 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1038 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1039 HeapFree(GetProcessHeap(), 0, pbTemp);
1041 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1042 ok(result, "%08x\n", GetLastError());
1044 /* Setting the salt also succeeds... */
1045 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1046 ok(result, "setting salt failed: %08x\n", GetLastError());
1047 /* but the resulting salt length is now zero? */
1049 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1050 ok(result, "%08x\n", GetLastError());
1052 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1053 "unexpected salt length %d\n", dwLen);
1054 /* What sizes salt can I set? */
1055 salt.pbData = pbData;
1056 for (i=0; i<24; i++)
1059 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1060 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1061 /* The returned salt length is the same as the set salt length */
1062 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1063 ok(result, "%08x\n", GetLastError());
1064 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1067 SetLastError(0xdeadbeef);
1068 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1070 broken(result), /* Win9x, WinMe, NT4, W2K */
1071 "%08x\n", GetLastError());
1073 result = CryptDestroyKey(hKey);
1074 ok(result, "%08x\n", GetLastError());
1077 /* Again, but test setting the effective key len */
1078 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1080 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1082 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1084 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1085 ok(result, "%08x\n", GetLastError());
1088 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1089 ok(result, "%08x\n", GetLastError());
1091 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1092 ok(result, "%08x\n", GetLastError());
1094 SetLastError(0xdeadbeef);
1095 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1096 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1098 SetLastError(0xdeadbeef);
1099 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1100 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1102 SetLastError(0xdeadbeef);
1103 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1105 dwLen = sizeof(dwKeyLen);
1106 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1107 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1108 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1109 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1112 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1113 ok(result, "%d\n", GetLastError());
1115 dwLen = sizeof(dwKeyLen);
1116 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1117 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1118 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1119 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1121 result = CryptDestroyHash(hHash);
1122 ok(result, "%08x\n", GetLastError());
1125 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1126 ok(result, "%08x\n", GetLastError());
1128 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1129 "RC2 encryption failed!\n");
1131 /* Oddly enough this succeeds, though it should have no effect */
1133 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1134 ok(result, "%d\n", GetLastError());
1136 result = CryptDestroyKey(hKey);
1137 ok(result, "%08x\n", GetLastError());
1141 static void test_rc4(void)
1143 static const BYTE rc4[16] = {
1144 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1145 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1149 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1150 unsigned char pbData[2000], *pbTemp;
1151 unsigned char pszBuffer[256];
1154 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1157 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1159 /* rsaenh compiled without OpenSSL */
1160 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1162 CRYPT_INTEGER_BLOB salt;
1164 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1165 ok(result, "%08x\n", GetLastError());
1168 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1169 ok(result, "%08x\n", GetLastError());
1171 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1172 ok(result, "%08x\n", GetLastError());
1174 dwLen = sizeof(DWORD);
1175 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1176 ok(result, "%08x\n", GetLastError());
1178 dwLen = sizeof(DWORD);
1179 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1180 ok(result, "%08x\n", GetLastError());
1182 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1183 ok(result, "%08x\n", GetLastError());
1184 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1185 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1186 HeapFree(GetProcessHeap(), 0, pbTemp);
1188 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1189 ok(result, "%08x\n", GetLastError());
1190 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1191 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1192 HeapFree(GetProcessHeap(), 0, pbTemp);
1194 dwLen = sizeof(DWORD);
1195 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1197 result = CryptDestroyHash(hHash);
1198 ok(result, "%08x\n", GetLastError());
1201 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1202 ok(result, "%08x\n", GetLastError());
1204 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1205 ok(result, "%08x\n", GetLastError());
1207 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1209 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1210 ok(result, "%08x\n", GetLastError());
1212 /* Setting the salt also succeeds... */
1213 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1214 ok(result, "setting salt failed: %08x\n", GetLastError());
1215 /* but the resulting salt length is now zero? */
1217 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1218 ok(result, "%08x\n", GetLastError());
1220 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1221 "unexpected salt length %d\n", dwLen);
1222 /* What sizes salt can I set? */
1223 salt.pbData = pbData;
1224 for (i=0; i<24; i++)
1227 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1228 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1229 /* The returned salt length is the same as the set salt length */
1230 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1231 ok(result, "%08x\n", GetLastError());
1232 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1235 SetLastError(0xdeadbeef);
1236 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1238 broken(result), /* Win9x, WinMe, NT4, W2K */
1239 "%08x\n", GetLastError());
1241 result = CryptDestroyKey(hKey);
1242 ok(result, "%08x\n", GetLastError());
1246 static void test_hmac(void) {
1250 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1251 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1254 static const BYTE hmac[16] = {
1255 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1256 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1259 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1261 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1263 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1264 ok(result, "%08x\n", GetLastError());
1265 if (!result) return;
1267 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1268 ok(result, "%08x\n", GetLastError());
1270 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1271 ok(result, "%08x\n", GetLastError());
1273 dwLen = sizeof(abData)/sizeof(BYTE);
1274 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1275 ok(result, "%08x\n", GetLastError());
1277 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1279 result = CryptDestroyHash(hHash);
1280 ok(result, "%08x\n", GetLastError());
1282 result = CryptDestroyKey(hKey);
1283 ok(result, "%08x\n", GetLastError());
1285 /* Provoke errors */
1286 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1287 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1290 static void test_mac(void) {
1295 BYTE abData[256], abEnc[264];
1296 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1299 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1300 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1302 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1305 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1306 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1308 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1309 ok(result, "%08x\n", GetLastError());
1310 if (!result) return;
1312 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1313 ok(result, "%08x\n", GetLastError());
1315 dwLen = sizeof(abData)/sizeof(BYTE);
1316 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1317 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1319 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1321 result = CryptDestroyHash(hHash);
1322 ok(result, "%08x\n", GetLastError());
1324 result = CryptDestroyKey(hKey);
1325 ok(result, "%08x\n", GetLastError());
1327 /* Provoke errors */
1328 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1330 SetLastError(0xdeadbeef);
1331 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1332 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1333 broken(result), /* Win9x, WinMe, NT4, W2K */
1334 "%08x\n", GetLastError());
1336 result = CryptDestroyKey(hKey);
1337 ok(result, "%08x\n", GetLastError());
1340 static BYTE abPlainPrivateKey[596] = {
1341 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1342 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1343 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1344 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1345 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1346 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1347 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1348 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1349 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1350 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1351 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1352 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1353 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1354 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1355 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1356 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1357 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1358 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1359 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1360 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1361 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1362 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1363 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1364 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1365 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1366 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1367 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1368 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1369 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1370 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1371 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1372 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1373 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1374 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1375 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1376 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1377 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1378 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1379 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1380 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1381 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1382 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1383 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1384 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1385 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1386 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1387 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1388 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1389 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1390 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1391 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1392 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1393 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1394 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1395 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1396 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1397 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1398 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1399 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1400 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1401 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1402 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1403 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1404 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1405 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1406 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1407 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1408 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1409 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1410 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1411 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1412 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1413 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1414 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1415 0xf2, 0x5d, 0x58, 0x07
1418 static void test_import_private(void)
1421 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1423 static BYTE abSessionKey[148] = {
1424 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1425 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1426 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1427 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1428 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1429 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1430 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1431 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1432 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1433 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1434 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1435 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1436 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1437 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1438 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1439 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1440 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1441 0x04, 0x8c, 0x49, 0x92
1443 static BYTE abEncryptedMessage[12] = {
1444 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1445 0x1c, 0xfd, 0xde, 0x71
1448 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1449 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1451 /* rsaenh compiled without OpenSSL */
1452 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1456 dwLen = (DWORD)sizeof(abSessionKey);
1457 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1458 ok(result, "%08x\n", GetLastError());
1459 if (!result) return;
1462 dwLen = sizeof(DWORD);
1463 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1464 ok(result, "%08x\n", GetLastError());
1466 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1467 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1468 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1469 " got %08x\n", dwVal);
1471 dwLen = (DWORD)sizeof(abEncryptedMessage);
1472 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1473 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1474 "%08x, len: %d\n", GetLastError(), dwLen);
1475 CryptDestroyKey(hSessionKey);
1477 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1479 dwLen = (DWORD)sizeof(abSessionKey);
1480 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1481 ok(result, "%08x\n", GetLastError());
1482 CryptDestroyKey(hSessionKey);
1483 if (!result) return;
1485 dwLen = (DWORD)sizeof(abSessionKey);
1486 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1487 ok(result, "%08x\n", GetLastError());
1488 if (!result) return;
1490 CryptDestroyKey(hSessionKey);
1491 CryptDestroyKey(hKeyExchangeKey);
1494 static void test_verify_signature(void) {
1496 HCRYPTKEY hPubSignKey;
1497 BYTE abData[] = "Wine rocks!";
1499 BYTE abPubKey[148] = {
1500 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1501 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1502 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1503 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1504 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1505 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1506 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1507 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1508 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1509 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1510 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1511 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1512 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1513 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1514 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1515 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1516 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1517 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1518 0xe1, 0x21, 0x50, 0xac
1520 /* md2 with hash oid */
1521 BYTE abSignatureMD2[128] = {
1522 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1523 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1524 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1525 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1526 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1527 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1528 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1529 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1530 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1531 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1532 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1533 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1534 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1535 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1536 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1537 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1539 /* md2 without hash oid */
1540 BYTE abSignatureMD2NoOID[128] = {
1541 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1542 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1543 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1544 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1545 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1546 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1547 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1548 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1549 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1550 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1551 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1552 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1553 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1554 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1555 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1556 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1558 /* md4 with hash oid */
1559 BYTE abSignatureMD4[128] = {
1560 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1561 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1562 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1563 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1564 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1565 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1566 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1567 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1568 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1569 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1570 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1571 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1572 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1573 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1574 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1575 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1577 /* md4 without hash oid */
1578 BYTE abSignatureMD4NoOID[128] = {
1579 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1580 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1581 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1582 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1583 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1584 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1585 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1586 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1587 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1588 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1589 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1590 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1591 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1592 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1593 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1594 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1596 /* md5 with hash oid */
1597 BYTE abSignatureMD5[128] = {
1598 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1599 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1600 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1601 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1602 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1603 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1604 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1605 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1606 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1607 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1608 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1609 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1610 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1611 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1612 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1613 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1615 /* md5 without hash oid */
1616 BYTE abSignatureMD5NoOID[128] = {
1617 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1618 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1619 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1620 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1621 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1622 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1623 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1624 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1625 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1626 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1627 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1628 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1629 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1630 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1631 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1632 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1634 /* sha with hash oid */
1635 BYTE abSignatureSHA[128] = {
1636 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1637 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1638 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1639 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1640 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1641 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1642 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1643 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1644 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1645 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1646 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1647 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1648 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1649 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1650 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1651 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1653 /* sha without hash oid */
1654 BYTE abSignatureSHANoOID[128] = {
1655 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1656 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1657 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1658 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1659 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1660 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1661 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1662 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1663 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1664 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1665 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1666 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1667 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1668 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1669 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1670 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1673 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1674 ok(result, "%08x\n", GetLastError());
1675 if (!result) return;
1677 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1678 ok(result, "%08x\n", GetLastError());
1679 if (!result) return;
1681 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1682 ok(result, "%08x\n", GetLastError());
1683 if (!result) return;
1685 /*check that a NULL pointer signature is correctly handled*/
1686 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1687 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1688 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1691 /* check that we get a bad signature error when the signature is too short*/
1692 SetLastError(0xdeadbeef);
1693 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1694 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1695 broken(result), /* Win9x, WinMe, NT4 */
1696 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1698 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1699 ok(result, "%08x\n", GetLastError());
1700 if (!result) return;
1702 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1703 ok(result, "%08x\n", GetLastError());
1704 if (!result) return;
1706 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1707 * the OID at all. */
1708 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1709 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1710 if (result) return;*/
1712 CryptDestroyHash(hHash);
1714 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1715 ok(result, "%08x\n", GetLastError());
1716 if (!result) return;
1718 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1719 ok(result, "%08x\n", GetLastError());
1720 if (!result) return;
1722 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1723 ok(result, "%08x\n", GetLastError());
1724 if (!result) return;
1726 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1727 ok(result, "%08x\n", GetLastError());
1728 if (!result) return;
1730 CryptDestroyHash(hHash);
1732 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1733 ok(result, "%08x\n", GetLastError());
1734 if (!result) return;
1736 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1737 ok(result, "%08x\n", GetLastError());
1738 if (!result) return;
1740 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1741 ok(result, "%08x\n", GetLastError());
1742 if (!result) return;
1744 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1745 ok(result, "%08x\n", GetLastError());
1746 if (!result) return;
1748 CryptDestroyHash(hHash);
1750 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1751 ok(result, "%08x\n", GetLastError());
1752 if (!result) return;
1754 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1755 ok(result, "%08x\n", GetLastError());
1756 if (!result) return;
1758 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1759 ok(result, "%08x\n", GetLastError());
1760 if (!result) return;
1762 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1763 ok(result, "%08x\n", GetLastError());
1764 if (!result) return;
1766 CryptDestroyHash(hHash);
1767 CryptDestroyKey(hPubSignKey);
1770 static void test_rsa_encrypt(void)
1773 BYTE abData[2048] = "Wine rocks!";
1777 /* It is allowed to use the key exchange key for encryption/decryption */
1778 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1779 ok (result, "%08x\n", GetLastError());
1780 if (!result) return;
1783 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1784 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1785 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1787 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1788 ok (result, "%08x\n", GetLastError());
1789 if (!result) return;
1791 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1792 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1795 dwLen = sizeof(DWORD);
1796 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1797 ok(result, "%08x\n", GetLastError());
1799 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1800 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1801 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1802 " got %08x\n", dwVal);
1804 /* An RSA key doesn't support salt */
1805 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1806 ok(!result && GetLastError() == NTE_BAD_KEY,
1807 "expected NTE_BAD_KEY, got %08x\n", GetLastError());
1809 /* The key exchange key's public key may be exported.. */
1810 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1811 ok(result, "%08x\n", GetLastError());
1812 /* but its private key may not be. */
1813 SetLastError(0xdeadbeef);
1814 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1815 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1816 broken(result), /* Win9x/NT4 */
1817 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1818 /* Setting the permissions of the key exchange key isn't allowed, either. */
1819 dwVal |= CRYPT_EXPORT;
1820 SetLastError(0xdeadbeef);
1821 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1823 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1824 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1826 CryptDestroyKey(hRSAKey);
1828 /* It is not allowed to use the signature key for encryption/decryption */
1829 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1830 ok (result, "%08x\n", GetLastError());
1831 if (!result) return;
1834 dwLen = sizeof(DWORD);
1835 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1836 ok(result, "%08x\n", GetLastError());
1838 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1839 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1840 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1841 " got %08x\n", dwVal);
1843 /* The signature key's public key may also be exported.. */
1844 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1845 ok(result, "%08x\n", GetLastError());
1846 /* but its private key may not be. */
1847 SetLastError(0xdeadbeef);
1848 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1849 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1850 broken(result), /* Win9x/NT4 */
1851 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1852 /* Setting the permissions of the signature key isn't allowed, either. */
1853 dwVal |= CRYPT_EXPORT;
1854 SetLastError(0xdeadbeef);
1855 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1857 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1858 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1861 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1862 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1864 CryptDestroyKey(hRSAKey);
1867 static void test_import_export(void)
1869 DWORD dwLen, dwDataLen, dwVal;
1870 HCRYPTKEY hPublicKey, hPrivKey;
1873 BYTE emptyKey[2048], *exported_key;
1874 static BYTE abPlainPublicKey[84] = {
1875 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1876 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1877 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1878 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1879 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1880 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1881 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1882 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1883 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1884 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1885 0x11, 0x11, 0x11, 0x11
1887 static BYTE priv_key_with_high_bit[] = {
1888 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1889 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1890 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1891 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1892 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1893 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1894 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1895 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1896 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1897 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1898 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1899 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1900 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1901 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1902 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1903 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1904 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1905 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1906 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1907 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1908 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1909 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1910 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1911 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1912 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1913 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1914 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1915 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1916 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1917 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1918 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1919 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1920 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1921 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1922 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1923 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1924 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1925 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1926 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1927 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1928 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1929 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1930 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1931 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1932 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1933 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1934 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1935 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1936 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1937 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1938 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1939 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1940 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1941 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1942 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1943 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1944 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1945 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1946 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1947 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1948 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1949 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1950 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1951 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1952 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1953 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1954 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1955 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1956 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1957 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1958 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1959 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1960 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1961 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1962 0xb6, 0x5f, 0x01, 0x5e
1964 static const BYTE expected_exported_priv_key[] = {
1965 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1966 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1967 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1968 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1969 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1970 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1971 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1972 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1973 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1974 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1975 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1976 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1977 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1978 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1979 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1980 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1981 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1982 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1983 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1984 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1985 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1986 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1987 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1988 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1989 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1990 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1991 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1992 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1993 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1994 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1995 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1996 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1997 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1998 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1999 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2000 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2001 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2002 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2003 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2004 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2005 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2006 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2007 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2008 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2009 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2010 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2011 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2012 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2013 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2014 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2015 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2016 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2017 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2018 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2019 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2020 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2021 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2022 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2023 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2024 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2025 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2026 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2027 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2028 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2029 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2030 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2031 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2032 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2033 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2034 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2035 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2036 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2037 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2038 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2039 0xb6, 0x5f, 0x01, 0x5e
2043 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2044 ok(result, "failed to import the public key\n");
2046 dwDataLen=sizeof(algID);
2047 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2048 ok(result, "failed to get the KP_ALGID from the imported public key\n");
2049 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2052 dwDataLen = sizeof(DWORD);
2053 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2054 ok(result, "%08x\n", GetLastError());
2056 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2057 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2058 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2059 " got %08x\n", dwVal);
2060 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2061 ok(result, "failed to export the fresh imported public key\n");
2062 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2063 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2065 CryptDestroyKey(hPublicKey);
2067 result = CryptImportKey(hProv, priv_key_with_high_bit,
2068 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2069 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2071 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2072 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2073 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2074 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2076 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2078 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2080 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2081 "unexpected value\n");
2083 HeapFree(GetProcessHeap(), 0, exported_key);
2085 CryptDestroyKey(hPrivKey);
2088 static void test_schannel_provider(void)
2091 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2092 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2095 SCHANNEL_ALG saSChannelAlg;
2096 CRYPT_DATA_BLOB data_blob;
2097 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2098 BYTE abTLS1Master[140] = {
2099 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2100 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2101 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2102 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2103 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2104 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2105 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2106 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2107 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2108 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2109 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2110 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2111 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2112 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2113 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2114 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2115 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2116 0xd3, 0x1e, 0x82, 0xb3
2118 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2119 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2120 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2121 BYTE abClientFinished[16] = "client finished";
2122 BYTE abData[16] = "Wine rocks!";
2124 static const BYTE abEncryptedData[16] = {
2125 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2126 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2128 static const BYTE abPRF[16] = {
2129 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2130 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2132 static const BYTE abMD5[16] = {
2133 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2134 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2137 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2140 win_skip("no PROV_RSA_SCHANNEL support\n");
2143 ok (result, "%08x\n", GetLastError());
2145 CryptReleaseContext(hProv, 0);
2147 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2148 ok (result, "%08x\n", GetLastError());
2149 if (!result) return;
2151 /* To get deterministic results, we import the TLS1 master secret (which
2152 * is typically generated from a random generator). Therefore, we need
2154 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2155 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2156 ok (result, "%08x\n", GetLastError());
2157 if (!result) return;
2159 dwLen = (DWORD)sizeof(abTLS1Master);
2160 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2161 ok (result, "%08x\n", GetLastError());
2162 if (!result) return;
2164 /* Setting the TLS1 client and server random parameters, as well as the
2165 * MAC and encryption algorithm parameters. */
2166 data_blob.cbData = 33;
2167 data_blob.pbData = abClientSecret;
2168 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2169 ok (result, "%08x\n", GetLastError());
2170 if (!result) return;
2172 data_blob.cbData = 33;
2173 data_blob.pbData = abServerSecret;
2174 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2175 ok (result, "%08x\n", GetLastError());
2176 if (!result) return;
2178 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2179 saSChannelAlg.Algid = CALG_DES;
2180 saSChannelAlg.cBits = 64;
2181 saSChannelAlg.dwFlags = 0;
2182 saSChannelAlg.dwReserved = 0;
2183 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2184 ok (result, "%08x\n", GetLastError());
2185 if (!result) return;
2187 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2188 saSChannelAlg.Algid = CALG_MD5;
2189 saSChannelAlg.cBits = 128;
2190 saSChannelAlg.dwFlags = 0;
2191 saSChannelAlg.dwReserved = 0;
2192 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2193 ok (result, "%08x\n", GetLastError());
2194 if (!result) return;
2196 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2197 * (Keys can only be derived from hashes, not from other keys.) */
2198 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2199 ok (result, "%08x\n", GetLastError());
2200 if (!result) return;
2202 /* Deriving the server write encryption key from the master hash */
2203 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2204 ok (result, "%08x\n", GetLastError());
2205 if (!result) return;
2207 /* Encrypting some data with the server write encryption key and checking the result. */
2209 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2210 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2212 /* Second test case: Test the TLS1 pseudo random number function. */
2213 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2214 ok (result, "%08x\n", GetLastError());
2215 if (!result) return;
2217 /* Set the label and seed parameters for the random number function */
2218 data_blob.cbData = 36;
2219 data_blob.pbData = abHashedHandshakes;
2220 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2221 ok (result, "%08x\n", GetLastError());
2222 if (!result) return;
2224 data_blob.cbData = 15;
2225 data_blob.pbData = abClientFinished;
2226 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2227 ok (result, "%08x\n", GetLastError());
2228 if (!result) return;
2230 /* Generate some pseudo random bytes and check if they are correct. */
2231 dwLen = (DWORD)sizeof(abData);
2232 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2233 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2234 "%08x\n", GetLastError());
2236 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2237 * Hash some data with the HMAC. Compare results. */
2238 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2239 ok (result, "%08x\n", GetLastError());
2240 if (!result) return;
2242 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2243 ok (result, "%08x\n", GetLastError());
2244 if (!result) return;
2246 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2247 ok (result, "%08x\n", GetLastError());
2248 if (!result) return;
2250 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2251 ok (result, "%08x\n", GetLastError());
2252 if (!result) return;
2254 dwLen = (DWORD)sizeof(abMD5Hash);
2255 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2256 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2258 CryptDestroyHash(hHMAC);
2259 CryptDestroyHash(hTLS1PRF);
2260 CryptDestroyHash(hMasterHash);
2261 CryptDestroyKey(hServerWriteMACKey);
2262 CryptDestroyKey(hServerWriteKey);
2263 CryptDestroyKey(hRSAKey);
2264 CryptDestroyKey(hMasterSecret);
2265 CryptReleaseContext(hProv, 0);
2266 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2269 /* Test that a key can be used to encrypt data and exported, and that, when
2270 * the exported key is imported again, can be used to decrypt the original
2273 static void test_rsa_round_trip(void)
2275 static const char test_string[] = "Well this is a fine how-do-you-do.";
2277 HCRYPTKEY signKey, keyExchangeKey;
2279 BYTE data[256], *exportedKey;
2280 DWORD dataLen, keyLen;
2282 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2283 CRYPT_DELETEKEYSET);
2285 /* Generate a new key... */
2286 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2288 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2289 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2290 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2291 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2292 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2293 /* encrypt some data with it... */
2294 memcpy(data, test_string, strlen(test_string) + 1);
2295 dataLen = strlen(test_string) + 1;
2296 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2298 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2299 "CryptEncrypt failed: %08x\n", GetLastError());
2300 /* export the key... */
2301 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2303 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2304 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2305 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2307 /* destroy the key... */
2308 CryptDestroyKey(keyExchangeKey);
2309 CryptDestroyKey(signKey);
2310 /* import the key again... */
2311 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2312 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2313 HeapFree(GetProcessHeap(), 0, exportedKey);
2314 /* and decrypt the data encrypted with the original key with the imported
2317 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2318 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2319 "CryptDecrypt failed: %08x\n", GetLastError());
2322 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2323 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2325 CryptDestroyKey(keyExchangeKey);
2326 CryptReleaseContext(prov, 0);
2328 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2329 CRYPT_DELETEKEYSET);
2332 static void test_enum_container(void)
2334 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2336 BOOL result, fFound = FALSE;
2338 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2339 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2340 SetLastError(0xdeadbeef);
2341 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2342 ok (result, "%08x\n", GetLastError());
2343 ok (dwBufferLen == MAX_PATH + 1 ||
2344 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2345 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2347 /* If the result fits into abContainerName dwBufferLen is left untouched */
2348 dwBufferLen = (DWORD)sizeof(abContainerName);
2349 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2350 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2352 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2354 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2355 dwBufferLen = (DWORD)sizeof(abContainerName);
2356 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2358 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2361 static BYTE signBlob[] = {
2362 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2363 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2364 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2365 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2366 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2367 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2368 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2369 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2370 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2371 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2372 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2373 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2374 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2375 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2376 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2377 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2378 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2379 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2380 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2381 0xb6,0x85,0x86,0x07 };
2383 static void test_null_provider(void)
2388 DWORD keySpec, dataLen,dwParam;
2389 char szName[MAX_PATH];
2391 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2392 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2393 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2394 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2395 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2396 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2397 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2398 CRYPT_DELETEKEYSET);
2399 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2400 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2401 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2402 CRYPT_DELETEKEYSET);
2403 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2404 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2405 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2406 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2407 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2409 /* Delete the default container. */
2410 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2411 /* Once you've deleted the default container you can't open it as if it
2414 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2415 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2416 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2417 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2418 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2419 CRYPT_VERIFYCONTEXT);
2420 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2421 if (!result) return;
2422 dataLen = sizeof(keySpec);
2423 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2425 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2426 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2427 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2428 * supported, you can't get the keys from this container.
2430 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2431 ok(!result && GetLastError() == NTE_NO_KEY,
2432 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2433 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2434 ok(!result && GetLastError() == NTE_NO_KEY,
2435 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2436 result = CryptReleaseContext(prov, 0);
2437 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2438 /* You can create a new default container. */
2439 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2441 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2442 /* But you still can't get the keys (until one's been generated.) */
2443 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2444 ok(!result && GetLastError() == NTE_NO_KEY,
2445 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2446 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2447 ok(!result && GetLastError() == NTE_NO_KEY,
2448 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2449 CryptReleaseContext(prov, 0);
2450 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2452 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2453 CRYPT_DELETEKEYSET);
2454 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2455 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2456 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2457 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2458 CRYPT_VERIFYCONTEXT);
2459 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2460 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2461 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2463 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2464 if (!result) return;
2465 /* Test provider parameters getter */
2466 dataLen = sizeof(dwParam);
2467 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2468 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2469 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2470 dataLen = sizeof(dwParam);
2471 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2472 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2473 "Expected 0, got 0x%08X\n",dwParam);
2474 dataLen = sizeof(dwParam);
2475 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2476 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2477 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2478 dataLen = sizeof(keySpec);
2479 SetLastError(0xdeadbeef);
2480 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2481 if (!result && GetLastError() == NTE_BAD_TYPE)
2482 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2484 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2485 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2486 /* PP_CONTAINER parameter */
2487 dataLen = sizeof(szName);
2488 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2489 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2490 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2491 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2492 /* PP_UNIQUE_CONTAINER parameter */
2493 dataLen = sizeof(szName);
2494 SetLastError(0xdeadbeef);
2495 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2496 if (!result && GetLastError() == NTE_BAD_TYPE)
2498 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2502 char container[MAX_PATH];
2504 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2505 uniquecontainer(container);
2508 ok(dataLen == strlen(container)+1 ||
2509 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2510 "Expected a param length of 70, got %d\n", dataLen);
2511 ok(!strcmp(container, szName) ||
2512 broken(!strcmp(szName, szContainer)) /* WinME */,
2513 "Wrong container name : %s\n", szName);
2516 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2517 ok(!result && GetLastError() == NTE_NO_KEY,
2518 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2519 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2520 ok(!result && GetLastError() == NTE_NO_KEY,
2521 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2523 /* Importing a key exchange blob.. */
2524 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2526 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2527 CryptDestroyKey(key);
2528 /* allows access to the key exchange key.. */
2529 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2530 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2531 CryptDestroyKey(key);
2532 /* but not to the private key. */
2533 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2534 ok(!result && GetLastError() == NTE_NO_KEY,
2535 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2536 CryptReleaseContext(prov, 0);
2537 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2538 CRYPT_DELETEKEYSET);
2540 /* Whereas importing a sign blob.. */
2541 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2543 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2544 if (!result) return;
2545 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2546 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2547 CryptDestroyKey(key);
2548 /* doesn't allow access to the key exchange key.. */
2549 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2550 ok(!result && GetLastError() == NTE_NO_KEY,
2551 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2552 /* but does to the private key. */
2553 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2554 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2555 CryptDestroyKey(key);
2556 CryptReleaseContext(prov, 0);
2558 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2559 CRYPT_DELETEKEYSET);
2561 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2562 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2564 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2565 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2566 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2567 CryptDestroyKey(key);
2568 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2569 ok(!result, "expected CryptGetUserKey to fail\n");
2570 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2571 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2572 CryptDestroyKey(key);
2573 CryptReleaseContext(prov, 0);
2575 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2576 CRYPT_DELETEKEYSET);
2578 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2579 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2581 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2582 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2583 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2584 CryptDestroyKey(key);
2585 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2586 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2587 CryptDestroyKey(key);
2588 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2589 ok(!result, "expected CryptGetUserKey to fail\n");
2590 CryptReleaseContext(prov, 0);
2592 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2593 CRYPT_DELETEKEYSET);
2595 /* test for the bug in accessing the user key in a container
2597 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2599 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2600 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2601 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2602 CryptDestroyKey(key);
2603 CryptReleaseContext(prov,0);
2604 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2605 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2606 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2607 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2608 CryptDestroyKey(key);
2609 CryptReleaseContext(prov, 0);
2611 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2612 CRYPT_DELETEKEYSET);
2614 /* test the machine key set */
2615 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2616 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2617 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2618 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2619 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2620 CryptReleaseContext(prov, 0);
2621 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2622 CRYPT_MACHINE_KEYSET);
2623 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2624 CryptReleaseContext(prov,0);
2625 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2626 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2627 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2629 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2630 CRYPT_MACHINE_KEYSET);
2631 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2632 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2636 static void test_key_permissions(void)
2638 HCRYPTKEY hKey1, hKey2;
2642 /* Create keys that are exportable */
2643 if (!init_base_environment(CRYPT_EXPORTABLE))
2646 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2647 ok (result, "%08x\n", GetLastError());
2648 if (!result) return;
2651 dwLen = sizeof(DWORD);
2652 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2653 ok(result, "%08x\n", GetLastError());
2655 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2656 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2657 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2658 " got %08x\n", dwVal);
2660 /* The key exchange key's public key may be exported.. */
2661 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2662 ok(result, "%08x\n", GetLastError());
2663 /* and its private key may be too. */
2664 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2665 ok(result, "%08x\n", GetLastError());
2666 /* Turning off the key's export permissions is "allowed".. */
2667 dwVal &= ~CRYPT_EXPORT;
2668 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2670 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2671 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2672 "%08x\n", GetLastError());
2673 /* but it has no effect. */
2675 dwLen = sizeof(DWORD);
2676 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2677 ok(result, "%08x\n", GetLastError());
2679 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2680 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2681 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2682 " got %08x\n", dwVal);
2683 /* Thus, changing the export flag of the key doesn't affect whether the key
2686 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2687 ok(result, "%08x\n", GetLastError());
2689 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2690 ok (result, "%08x\n", GetLastError());
2692 /* A subsequent get of the same key, into a different handle, also doesn't
2693 * show that the permissions have been changed.
2696 dwLen = sizeof(DWORD);
2697 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2698 ok(result, "%08x\n", GetLastError());
2700 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2701 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2702 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2703 " got %08x\n", dwVal);
2705 CryptDestroyKey(hKey2);
2706 CryptDestroyKey(hKey1);
2708 clean_up_base_environment();
2711 static void test_key_initialization(void)
2714 HCRYPTPROV prov1, prov2;
2715 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2717 static BYTE abSessionKey[148] = {
2718 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2719 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2720 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2721 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2722 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2723 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2724 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2725 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2726 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2727 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2728 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2729 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2730 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2731 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2732 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2733 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2734 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2735 0x04, 0x8c, 0x49, 0x92
2738 /* Like init_base_environment, but doesn't generate new keys, as they'll
2739 * be imported instead.
2741 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2743 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2745 ok(result, "%08x\n", GetLastError());
2747 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2748 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2750 dwLen = (DWORD)sizeof(abSessionKey);
2751 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2752 ok(result, "%08x\n", GetLastError());
2754 /* Once the key has been imported, subsequently acquiring a context with
2755 * the same name will allow retrieving the key.
2757 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2758 ok(result, "%08x\n", GetLastError());
2759 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2760 ok(result, "%08x\n", GetLastError());
2761 if (result) CryptDestroyKey(hKey);
2762 CryptReleaseContext(prov2, 0);
2764 CryptDestroyKey(hSessionKey);
2765 CryptDestroyKey(hKeyExchangeKey);
2766 CryptReleaseContext(prov1, 0);
2767 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2768 CRYPT_DELETEKEYSET);
2773 if (!init_base_environment(0))
2785 test_block_cipher_modes();
2786 test_import_private();
2787 test_verify_signature();
2789 test_import_export();
2790 test_enum_container();
2791 clean_up_base_environment();
2792 test_key_permissions();
2793 test_key_initialization();
2794 test_schannel_provider();
2795 test_null_provider();
2796 test_rsa_round_trip();
2797 if (!init_aes_environment())
2803 clean_up_aes_environment();