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;
76 /* Get the MachineGUID */
77 RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
78 RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
81 lstrcpy(unique, szContainer_md5);
83 lstrcat(unique, guid);
86 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
89 printf("%s: ",heading);
91 printf("0x%02x,",pb[i]);
95 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
98 static void trace_hex(BYTE *pbData, DWORD dwLen) {
102 for (i = 0; i < dwLen-7; i+=8) {
103 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
104 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
105 pbData[i+6], pbData[i+7]);
108 for (j=0; i<dwLen; j++,i++) {
109 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
115 static int init_base_environment(DWORD dwKeyFlags)
120 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
122 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
124 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
125 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
127 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
129 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
130 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
131 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
133 ok(result, "%08x\n", GetLastError());
134 if (!result) return 0;
135 result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey);
136 ok(result, "%08x\n", GetLastError());
137 if (result) CryptDestroyKey(hKey);
138 result = CryptGenKey(hProv, AT_SIGNATURE, dwKeyFlags, &hKey);
139 ok(result, "%08x\n", GetLastError());
140 if (result) CryptDestroyKey(hKey);
145 static void clean_up_base_environment(void)
149 SetLastError(0xdeadbeef);
150 result = CryptReleaseContext(hProv, 1);
151 ok(!result || broken(result) /* Win98 */, "Expected failure\n");
152 ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
154 /* Just to prove that Win98 also released the CSP */
155 SetLastError(0xdeadbeef);
156 result = CryptReleaseContext(hProv, 0);
157 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
159 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
162 static int init_aes_environment(void)
167 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
169 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
171 /* we are using NULL as provider name for RSA_AES provider as the provider
172 * names are different in Windows XP and Vista. Its different as to what
173 * its defined in the SDK on Windows XP.
174 * This provider is available on Windows XP, Windows 2003 and Vista. */
176 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
177 if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
179 win_skip("RSA_ASE provider not supported\n");
182 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
184 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
186 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
187 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
188 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
190 ok(result, "%08x\n", GetLastError());
191 if (!result) return 0;
192 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
193 ok(result, "%08x\n", GetLastError());
194 if (result) CryptDestroyKey(hKey);
195 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
196 ok(result, "%08x\n", GetLastError());
197 if (result) CryptDestroyKey(hKey);
202 static void clean_up_aes_environment(void)
206 result = CryptReleaseContext(hProv, 1);
207 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
209 CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
212 static void test_prov(void)
217 dwLen = (DWORD)sizeof(DWORD);
218 SetLastError(0xdeadbeef);
219 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
220 if (!result && GetLastError() == NTE_BAD_TYPE)
221 skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
223 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
225 dwLen = (DWORD)sizeof(DWORD);
226 SetLastError(0xdeadbeef);
227 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
228 if (!result && GetLastError() == NTE_BAD_TYPE)
229 skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
231 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
234 static void test_gen_random(void)
237 BYTE rnd1[16], rnd2[16];
239 memset(rnd1, 0, sizeof(rnd1));
240 memset(rnd2, 0, sizeof(rnd2));
242 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
243 if (!result && GetLastError() == NTE_FAIL) {
244 /* rsaenh compiled without OpenSSL */
248 ok(result, "%08x\n", GetLastError());
250 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
251 ok(result, "%08x\n", GetLastError());
253 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
256 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
260 unsigned char pbData[2000];
264 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
265 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
267 /* rsaenh compiled without OpenSSL */
268 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
271 ok(result, "%08x\n", GetLastError());
272 if (!result) return FALSE;
273 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
274 ok(result, "%08x\n", GetLastError());
275 if (!result) return FALSE;
276 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
277 ok(result, "%08x\n", GetLastError());
278 if (!result) return FALSE;
280 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
281 ok(result, "%08x\n", GetLastError());
282 CryptDestroyHash(hHash);
286 static void test_hashes(void)
288 static const unsigned char md2hash[16] = {
289 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
290 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
291 static const unsigned char md4hash[16] = {
292 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
293 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
294 static const unsigned char empty_md5hash[16] = {
295 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
296 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
297 static const unsigned char md5hash[16] = {
298 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
299 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
300 static const unsigned char sha1hash[20] = {
301 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
302 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
303 unsigned char pbData[2048];
305 HCRYPTHASH hHash, hHashClone;
306 BYTE pbHashValue[36];
310 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
313 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
315 /* rsaenh compiled without OpenSSL */
316 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
318 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
319 ok(result, "%08x\n", GetLastError());
322 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
323 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
326 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
327 ok(result, "%08x\n", GetLastError());
329 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
331 result = CryptDestroyHash(hHash);
332 ok(result, "%08x\n", GetLastError());
336 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
337 ok(result, "%08x\n", GetLastError());
339 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
340 ok(result, "%08x\n", GetLastError());
343 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
344 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
347 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
348 ok(result, "%08x\n", GetLastError());
350 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
352 result = CryptDestroyHash(hHash);
353 ok(result, "%08x\n", GetLastError());
356 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
357 ok(result, "%08x\n", GetLastError());
360 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
361 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
363 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
364 ok(result, "%08x\n", GetLastError());
367 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
368 ok(result, "%08x\n", GetLastError());
370 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
372 result = CryptDestroyHash(hHash);
373 ok(result, "%08x\n", GetLastError());
375 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
376 ok(result, "%08x\n", GetLastError());
378 /* The hash is available even if CryptHashData hasn't been called */
380 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
381 ok(result, "%08x\n", GetLastError());
383 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
385 /* It's also stable: getting it twice results in the same value */
386 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
387 ok(result, "%08x\n", GetLastError());
389 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
391 /* Can't add data after the hash been retrieved */
392 SetLastError(0xdeadbeef);
393 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
394 ok(!result, "Expected failure\n");
395 ok(GetLastError() == NTE_BAD_HASH_STATE ||
396 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
397 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
399 /* You can still retrieve the hash, its value just hasn't changed */
400 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
401 ok(result, "%08x\n", GetLastError());
403 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
405 result = CryptDestroyHash(hHash);
406 ok(result, "%08x\n", GetLastError());
409 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
410 ok(result, "%08x\n", GetLastError());
412 result = CryptHashData(hHash, pbData, 5, 0);
413 ok(result, "%08x\n", GetLastError());
415 if(pCryptDuplicateHash) {
416 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
417 ok(result, "%08x\n", GetLastError());
419 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
420 ok(result, "%08x\n", GetLastError());
423 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
424 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
427 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
428 ok(result, "%08x\n", GetLastError());
430 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
432 result = CryptDestroyHash(hHashClone);
433 ok(result, "%08x\n", GetLastError());
436 result = CryptDestroyHash(hHash);
437 ok(result, "%08x\n", GetLastError());
440 static void test_block_cipher_modes(void)
442 static const BYTE plain[23] = {
443 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
444 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
445 static const BYTE ecb[24] = {
446 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
447 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
448 static const BYTE cbc[24] = {
449 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
450 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
451 static const BYTE cfb[24] = {
452 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
453 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
459 result = derive_key(CALG_RC2, &hKey, 40);
462 memcpy(abData, plain, sizeof(abData));
464 dwMode = CRYPT_MODE_ECB;
465 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
466 ok(result, "%08x\n", GetLastError());
469 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
470 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
471 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
473 SetLastError(ERROR_SUCCESS);
475 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
476 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
477 "%08x, dwLen: %d\n", GetLastError(), dwLen);
479 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
480 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
481 "%08x, dwLen: %d\n", GetLastError(), dwLen);
483 dwMode = CRYPT_MODE_CBC;
484 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
485 ok(result, "%08x\n", GetLastError());
488 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
489 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
490 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
493 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
494 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
495 "%08x, dwLen: %d\n", GetLastError(), dwLen);
497 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
498 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
499 "%08x, dwLen: %d\n", GetLastError(), dwLen);
501 dwMode = CRYPT_MODE_CFB;
502 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
503 ok(result, "%08x\n", GetLastError());
506 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
507 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
510 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
511 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
512 "%08x, dwLen: %d\n", GetLastError(), dwLen);
515 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
516 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
519 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
520 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
521 "%08x, dwLen: %d\n", GetLastError(), dwLen);
523 dwMode = CRYPT_MODE_OFB;
524 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
525 ok(result, "%08x\n", GetLastError());
528 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
529 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
531 CryptDestroyKey(hKey);
534 static void test_3des112(void)
539 unsigned char pbData[16];
542 result = derive_key(CALG_3DES_112, &hKey, 0);
544 /* rsaenh compiled without OpenSSL */
545 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
549 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
552 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
553 ok(result, "%08x\n", GetLastError());
555 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
556 ok(result, "%08x\n", GetLastError());
560 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
562 dwLen = cTestData[i].enclen;
563 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
564 ok(result, "%08x\n", GetLastError());
565 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
567 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
568 ok(result, "%08x\n", GetLastError());
569 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
570 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
571 if((dwLen != cTestData[i].enclen) ||
572 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
574 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
575 printBytes("got",pbData,dwLen);
578 result = CryptDestroyKey(hKey);
579 ok(result, "%08x\n", GetLastError());
582 static void test_des(void)
587 unsigned char pbData[16];
590 result = derive_key(CALG_DES, &hKey, 56);
592 /* rsaenh compiled without OpenSSL */
593 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
597 dwMode = CRYPT_MODE_ECB;
598 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
599 ok(result, "%08x\n", GetLastError());
601 dwLen = sizeof(DWORD);
602 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
603 ok(result, "%08x\n", GetLastError());
605 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
608 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
609 ok(result, "%08x\n", GetLastError());
611 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
612 ok(result, "%08x\n", GetLastError());
616 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
618 dwLen = cTestData[i].enclen;
619 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
620 ok(result, "%08x\n", GetLastError());
621 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
623 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
624 ok(result, "%08x\n", GetLastError());
625 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
626 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
627 if((dwLen != cTestData[i].enclen) ||
628 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
630 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
631 printBytes("got",pbData,dwLen);
635 result = CryptDestroyKey(hKey);
636 ok(result, "%08x\n", GetLastError());
639 static void test_3des(void)
644 unsigned char pbData[16];
645 static const BYTE des3[16] = {
646 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
647 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
650 result = derive_key(CALG_3DES, &hKey, 0);
653 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
656 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
657 ok(result, "%08x\n", GetLastError());
659 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
661 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
662 ok(result, "%08x\n", GetLastError());
666 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
668 dwLen = cTestData[i].enclen;
669 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
670 ok(result, "%08x\n", GetLastError());
671 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
673 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
674 ok(result, "%08x\n", GetLastError());
675 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
676 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
677 if((dwLen != cTestData[i].enclen) ||
678 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
680 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
681 printBytes("got",pbData,dwLen);
684 result = CryptDestroyKey(hKey);
685 ok(result, "%08x\n", GetLastError());
688 static void test_aes(int keylen)
693 unsigned char pbData[16];
699 result = derive_key(CALG_AES_256, &hKey, 0);
702 result = derive_key(CALG_AES_192, &hKey, 0);
706 result = derive_key(CALG_AES_128, &hKey, 0);
711 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
714 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
715 ok(result, "%08x\n", GetLastError());
717 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
718 ok(result, "%08x\n", GetLastError());
722 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
724 dwLen = cTestData[i].enclen;
725 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
726 ok(result, "%08x\n", GetLastError());
727 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
729 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
730 ok(result, "%08x\n", GetLastError());
731 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
732 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
733 if((dwLen != cTestData[i].enclen) ||
734 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
736 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
737 printBytes("got",pbData,dwLen);
740 result = CryptDestroyKey(hKey);
741 ok(result, "%08x\n", GetLastError());
744 static void test_rc2(void)
746 static const BYTE rc2_40_encrypted[16] = {
747 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
748 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
749 static const BYTE rc2_128_encrypted[] = {
750 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
755 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
757 unsigned char pbData[2000], pbHashValue[16];
760 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
763 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
765 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
767 CRYPT_INTEGER_BLOB salt;
769 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
770 ok(result, "%08x\n", GetLastError());
773 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
774 ok(result, "%08x\n", GetLastError());
776 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
777 ok(result, "%08x\n", GetLastError());
779 dwLen = sizeof(DWORD);
780 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
781 ok(result, "%08x\n", GetLastError());
783 dwMode = CRYPT_MODE_CBC;
784 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
785 ok(result, "%08x\n", GetLastError());
787 dwLen = sizeof(DWORD);
788 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
789 ok(result, "%08x\n", GetLastError());
791 dwModeBits = 0xdeadbeef;
792 dwLen = sizeof(DWORD);
793 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
794 ok(result, "%08x\n", GetLastError());
796 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT),
797 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
798 " got %08x\n", dwModeBits);
800 dwLen = sizeof(DWORD);
801 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
802 ok(result, "%08x\n", GetLastError());
804 dwLen = sizeof(DWORD);
805 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
806 ok(result, "%08x\n", GetLastError());
808 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
809 ok(result, "%08x\n", GetLastError());
810 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
811 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
812 HeapFree(GetProcessHeap(), 0, pbTemp);
814 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
815 ok(result, "%08x\n", GetLastError());
816 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
817 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
818 HeapFree(GetProcessHeap(), 0, pbTemp);
820 dwLen = sizeof(DWORD);
821 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
823 result = CryptDestroyHash(hHash);
824 ok(result, "%08x\n", GetLastError());
827 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
828 ok(result, "%08x\n", GetLastError());
830 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
832 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
833 ok(result, "%08x\n", GetLastError());
834 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
835 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
836 HeapFree(GetProcessHeap(), 0, pbTemp);
838 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
839 ok(result, "%08x\n", GetLastError());
841 /* What sizes salt can I set? */
842 salt.pbData = pbData;
846 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
847 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
850 SetLastError(0xdeadbeef);
851 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
853 broken(result), /* Win9x, WinMe, NT4, W2K */
854 "%08x\n", GetLastError());
856 result = CryptDestroyKey(hKey);
857 ok(result, "%08x\n", GetLastError());
860 /* Again, but test setting the effective key len */
861 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
863 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
865 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
867 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
868 ok(result, "%08x\n", GetLastError());
871 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
872 ok(result, "%08x\n", GetLastError());
874 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
875 ok(result, "%08x\n", GetLastError());
877 SetLastError(0xdeadbeef);
878 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
879 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
881 SetLastError(0xdeadbeef);
882 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
883 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
885 SetLastError(0xdeadbeef);
886 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
888 dwLen = sizeof(dwKeyLen);
889 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
890 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
891 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
892 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
895 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
896 ok(result, "%d\n", GetLastError());
898 dwLen = sizeof(dwKeyLen);
899 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
900 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
901 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
902 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
904 result = CryptDestroyHash(hHash);
905 ok(result, "%08x\n", GetLastError());
908 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
909 ok(result, "%08x\n", GetLastError());
911 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
912 "RC2 encryption failed!\n");
914 /* Oddly enough this succeeds, though it should have no effect */
916 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
917 ok(result, "%d\n", GetLastError());
919 result = CryptDestroyKey(hKey);
920 ok(result, "%08x\n", GetLastError());
924 static void test_rc4(void)
926 static const BYTE rc4[16] = {
927 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
928 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
932 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
933 unsigned char pbData[2000], *pbTemp;
934 unsigned char pszBuffer[256];
937 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
940 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
942 /* rsaenh compiled without OpenSSL */
943 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
945 CRYPT_INTEGER_BLOB salt;
947 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
948 ok(result, "%08x\n", GetLastError());
951 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
952 ok(result, "%08x\n", GetLastError());
954 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
955 ok(result, "%08x\n", GetLastError());
957 dwLen = sizeof(DWORD);
958 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
959 ok(result, "%08x\n", GetLastError());
961 dwLen = sizeof(DWORD);
962 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
963 ok(result, "%08x\n", GetLastError());
965 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
966 ok(result, "%08x\n", GetLastError());
967 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
968 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
969 HeapFree(GetProcessHeap(), 0, pbTemp);
971 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
972 ok(result, "%08x\n", GetLastError());
973 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
974 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
975 HeapFree(GetProcessHeap(), 0, pbTemp);
977 dwLen = sizeof(DWORD);
978 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
980 result = CryptDestroyHash(hHash);
981 ok(result, "%08x\n", GetLastError());
984 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
985 ok(result, "%08x\n", GetLastError());
987 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
988 ok(result, "%08x\n", GetLastError());
990 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
992 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
993 ok(result, "%08x\n", GetLastError());
995 /* What sizes salt can I set? */
996 salt.pbData = pbData;
1000 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1001 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1004 SetLastError(0xdeadbeef);
1005 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1007 broken(result), /* Win9x, WinMe, NT4, W2K */
1008 "%08x\n", GetLastError());
1010 result = CryptDestroyKey(hKey);
1011 ok(result, "%08x\n", GetLastError());
1015 static void test_hmac(void) {
1019 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1020 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1023 static const BYTE hmac[16] = {
1024 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1025 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1028 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1030 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1032 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1033 ok(result, "%08x\n", GetLastError());
1034 if (!result) return;
1036 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1037 ok(result, "%08x\n", GetLastError());
1039 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1040 ok(result, "%08x\n", GetLastError());
1042 dwLen = sizeof(abData)/sizeof(BYTE);
1043 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1044 ok(result, "%08x\n", GetLastError());
1046 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1048 result = CryptDestroyHash(hHash);
1049 ok(result, "%08x\n", GetLastError());
1051 result = CryptDestroyKey(hKey);
1052 ok(result, "%08x\n", GetLastError());
1054 /* Provoke errors */
1055 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1056 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1059 static void test_mac(void) {
1064 BYTE abData[256], abEnc[264];
1065 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1068 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1069 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1071 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1074 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1075 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1077 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1078 ok(result, "%08x\n", GetLastError());
1079 if (!result) return;
1081 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1082 ok(result, "%08x\n", GetLastError());
1084 dwLen = sizeof(abData)/sizeof(BYTE);
1085 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1086 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1088 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1090 result = CryptDestroyHash(hHash);
1091 ok(result, "%08x\n", GetLastError());
1093 result = CryptDestroyKey(hKey);
1094 ok(result, "%08x\n", GetLastError());
1096 /* Provoke errors */
1097 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1099 SetLastError(0xdeadbeef);
1100 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1101 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1102 broken(result), /* Win9x, WinMe, NT4, W2K */
1103 "%08x\n", GetLastError());
1105 result = CryptDestroyKey(hKey);
1106 ok(result, "%08x\n", GetLastError());
1109 static BYTE abPlainPrivateKey[596] = {
1110 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1111 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1112 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1113 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1114 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1115 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1116 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1117 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1118 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1119 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1120 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1121 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1122 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1123 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1124 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1125 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1126 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1127 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1128 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1129 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1130 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1131 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1132 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1133 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1134 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1135 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1136 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1137 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1138 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1139 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1140 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1141 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1142 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1143 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1144 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1145 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1146 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1147 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1148 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1149 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1150 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1151 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1152 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1153 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1154 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1155 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1156 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1157 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1158 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1159 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1160 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1161 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1162 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1163 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1164 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1165 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1166 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1167 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1168 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1169 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1170 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1171 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1172 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1173 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1174 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1175 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1176 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1177 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1178 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1179 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1180 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1181 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1182 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1183 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1184 0xf2, 0x5d, 0x58, 0x07
1187 static void test_import_private(void)
1190 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1192 static BYTE abSessionKey[148] = {
1193 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1194 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1195 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1196 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1197 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1198 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1199 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1200 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1201 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1202 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1203 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1204 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1205 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1206 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1207 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1208 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1209 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1210 0x04, 0x8c, 0x49, 0x92
1212 static BYTE abEncryptedMessage[12] = {
1213 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1214 0x1c, 0xfd, 0xde, 0x71
1217 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1218 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1220 /* rsaenh compiled without OpenSSL */
1221 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1225 dwLen = (DWORD)sizeof(abSessionKey);
1226 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1227 ok(result, "%08x\n", GetLastError());
1228 if (!result) return;
1231 dwLen = sizeof(DWORD);
1232 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1233 ok(result, "%08x\n", GetLastError());
1235 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT),
1236 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1237 " got %08x\n", dwVal);
1239 dwLen = (DWORD)sizeof(abEncryptedMessage);
1240 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1241 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1242 "%08x, len: %d\n", GetLastError(), dwLen);
1243 CryptDestroyKey(hSessionKey);
1245 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1247 dwLen = (DWORD)sizeof(abSessionKey);
1248 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1249 ok(result, "%08x\n", GetLastError());
1250 CryptDestroyKey(hSessionKey);
1251 if (!result) return;
1253 dwLen = (DWORD)sizeof(abSessionKey);
1254 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1255 ok(result, "%08x\n", GetLastError());
1256 if (!result) return;
1258 CryptDestroyKey(hSessionKey);
1259 CryptDestroyKey(hKeyExchangeKey);
1262 static void test_verify_signature(void) {
1264 HCRYPTKEY hPubSignKey;
1265 BYTE abData[] = "Wine rocks!";
1267 BYTE abPubKey[148] = {
1268 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1269 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1270 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1271 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1272 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1273 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1274 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1275 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1276 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1277 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1278 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1279 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1280 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1281 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1282 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1283 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1284 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1285 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1286 0xe1, 0x21, 0x50, 0xac
1288 /* md2 with hash oid */
1289 BYTE abSignatureMD2[128] = {
1290 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1291 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1292 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1293 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1294 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1295 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1296 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1297 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1298 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1299 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1300 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1301 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1302 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1303 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1304 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1305 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1307 /* md2 without hash oid */
1308 BYTE abSignatureMD2NoOID[128] = {
1309 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1310 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1311 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1312 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1313 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1314 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1315 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1316 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1317 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1318 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1319 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1320 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1321 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1322 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1323 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1324 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1326 /* md4 with hash oid */
1327 BYTE abSignatureMD4[128] = {
1328 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1329 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1330 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1331 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1332 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1333 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1334 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1335 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1336 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1337 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1338 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1339 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1340 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1341 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1342 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1343 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1345 /* md4 without hash oid */
1346 BYTE abSignatureMD4NoOID[128] = {
1347 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1348 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1349 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1350 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1351 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1352 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1353 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1354 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1355 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1356 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1357 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1358 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1359 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1360 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1361 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1362 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1364 /* md5 with hash oid */
1365 BYTE abSignatureMD5[128] = {
1366 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1367 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1368 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1369 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1370 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1371 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1372 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1373 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1374 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1375 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1376 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1377 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1378 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1379 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1380 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1381 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1383 /* md5 without hash oid */
1384 BYTE abSignatureMD5NoOID[128] = {
1385 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1386 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1387 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1388 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1389 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1390 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1391 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1392 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1393 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1394 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1395 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1396 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1397 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1398 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1399 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1400 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1402 /* sha with hash oid */
1403 BYTE abSignatureSHA[128] = {
1404 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1405 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1406 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1407 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1408 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1409 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1410 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1411 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1412 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1413 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1414 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1415 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1416 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1417 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1418 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1419 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1421 /* sha without hash oid */
1422 BYTE abSignatureSHANoOID[128] = {
1423 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1424 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1425 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1426 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1427 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1428 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1429 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1430 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1431 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1432 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1433 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1434 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1435 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1436 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1437 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1438 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1441 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1442 ok(result, "%08x\n", GetLastError());
1443 if (!result) return;
1445 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1446 ok(result, "%08x\n", GetLastError());
1447 if (!result) return;
1449 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1450 ok(result, "%08x\n", GetLastError());
1451 if (!result) return;
1453 /*check that a NULL pointer signature is correctly handled*/
1454 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1455 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1456 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1459 /* check that we get a bad signature error when the signature is too short*/
1460 SetLastError(0xdeadbeef);
1461 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1462 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1463 broken(result), /* Win9x, WinMe, NT4 */
1464 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1466 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1467 ok(result, "%08x\n", GetLastError());
1468 if (!result) return;
1470 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1471 ok(result, "%08x\n", GetLastError());
1472 if (!result) return;
1474 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1475 * the OID at all. */
1476 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1477 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1478 if (result) return;*/
1480 CryptDestroyHash(hHash);
1482 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1483 ok(result, "%08x\n", GetLastError());
1484 if (!result) return;
1486 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1487 ok(result, "%08x\n", GetLastError());
1488 if (!result) return;
1490 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1491 ok(result, "%08x\n", GetLastError());
1492 if (!result) return;
1494 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1495 ok(result, "%08x\n", GetLastError());
1496 if (!result) return;
1498 CryptDestroyHash(hHash);
1500 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1501 ok(result, "%08x\n", GetLastError());
1502 if (!result) return;
1504 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1505 ok(result, "%08x\n", GetLastError());
1506 if (!result) return;
1508 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1509 ok(result, "%08x\n", GetLastError());
1510 if (!result) return;
1512 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1513 ok(result, "%08x\n", GetLastError());
1514 if (!result) return;
1516 CryptDestroyHash(hHash);
1518 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1519 ok(result, "%08x\n", GetLastError());
1520 if (!result) return;
1522 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1523 ok(result, "%08x\n", GetLastError());
1524 if (!result) return;
1526 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1527 ok(result, "%08x\n", GetLastError());
1528 if (!result) return;
1530 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1531 ok(result, "%08x\n", GetLastError());
1532 if (!result) return;
1534 CryptDestroyHash(hHash);
1535 CryptDestroyKey(hPubSignKey);
1538 static void test_rsa_encrypt(void)
1541 BYTE abData[2048] = "Wine rocks!";
1545 /* It is allowed to use the key exchange key for encryption/decryption */
1546 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1547 ok (result, "%08x\n", GetLastError());
1548 if (!result) return;
1551 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1552 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1553 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1555 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1556 ok (result, "%08x\n", GetLastError());
1557 if (!result) return;
1559 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1560 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1563 dwLen = sizeof(DWORD);
1564 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1565 ok(result, "%08x\n", GetLastError());
1567 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT),
1568 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1569 " got %08x\n", dwVal);
1571 /* The key exchange key's public key may be exported.. */
1572 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1573 ok(result, "%08x\n", GetLastError());
1574 /* but its private key may not be. */
1575 SetLastError(0xdeadbeef);
1576 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1577 ok(!result && GetLastError() == NTE_BAD_KEY_STATE,
1578 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1579 /* Setting the permissions of the key exchange key isn't allowed, either. */
1580 dwVal |= CRYPT_EXPORT;
1581 SetLastError(0xdeadbeef);
1582 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1583 ok(!result && GetLastError() == NTE_BAD_DATA,
1584 "expected NTE_BAD_DATA, got %08x\n", GetLastError());
1586 CryptDestroyKey(hRSAKey);
1588 /* It is not allowed to use the signature key for encryption/decryption */
1589 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1590 ok (result, "%08x\n", GetLastError());
1591 if (!result) return;
1594 dwLen = sizeof(DWORD);
1595 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1596 ok(result, "%08x\n", GetLastError());
1598 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT),
1599 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1600 " got %08x\n", dwVal);
1602 /* The signature key's public key may also be exported.. */
1603 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1604 ok(result, "%08x\n", GetLastError());
1605 /* but its private key may not be. */
1606 SetLastError(0xdeadbeef);
1607 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1608 ok(!result && GetLastError() == NTE_BAD_KEY_STATE,
1609 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1610 /* Setting the permissions of the signature key isn't allowed, either. */
1611 dwVal |= CRYPT_EXPORT;
1612 SetLastError(0xdeadbeef);
1613 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1614 ok(!result && GetLastError() == NTE_BAD_DATA,
1615 "expected NTE_BAD_DATA, got %08x\n", GetLastError());
1618 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1619 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1621 CryptDestroyKey(hRSAKey);
1624 static void test_import_export(void)
1626 DWORD dwLen, dwDataLen, dwVal;
1627 HCRYPTKEY hPublicKey;
1630 BYTE emptyKey[2048];
1631 static BYTE abPlainPublicKey[84] = {
1632 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1633 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1634 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1635 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1636 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1637 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1638 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1639 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1640 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1641 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1642 0x11, 0x11, 0x11, 0x11
1646 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1647 ok(result, "failed to import the public key\n");
1649 dwDataLen=sizeof(algID);
1650 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1651 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1652 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1655 dwDataLen = sizeof(DWORD);
1656 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
1657 ok(result, "%08x\n", GetLastError());
1659 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT),
1660 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1661 " got %08x\n", dwVal);
1662 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1663 ok(result, "failed to export the fresh imported public key\n");
1664 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1665 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1667 CryptDestroyKey(hPublicKey);
1670 static void test_schannel_provider(void)
1673 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1674 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1677 SCHANNEL_ALG saSChannelAlg;
1678 CRYPT_DATA_BLOB data_blob;
1679 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1680 BYTE abTLS1Master[140] = {
1681 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1682 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1683 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1684 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1685 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1686 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1687 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1688 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1689 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1690 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1691 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1692 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1693 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1694 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1695 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1696 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1697 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1698 0xd3, 0x1e, 0x82, 0xb3
1700 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1701 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1702 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1703 BYTE abClientFinished[16] = "client finished";
1704 BYTE abData[16] = "Wine rocks!";
1706 static const BYTE abEncryptedData[16] = {
1707 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1708 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1710 static const BYTE abPRF[16] = {
1711 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1712 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1714 static const BYTE abMD5[16] = {
1715 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1716 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1719 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1722 win_skip("no PROV_RSA_SCHANNEL support\n");
1725 ok (result, "%08x\n", GetLastError());
1727 CryptReleaseContext(hProv, 0);
1729 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1730 ok (result, "%08x\n", GetLastError());
1731 if (!result) return;
1733 /* To get deterministic results, we import the TLS1 master secret (which
1734 * is typically generated from a random generator). Therefore, we need
1736 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1737 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1738 ok (result, "%08x\n", GetLastError());
1739 if (!result) return;
1741 dwLen = (DWORD)sizeof(abTLS1Master);
1742 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1743 ok (result, "%08x\n", GetLastError());
1744 if (!result) return;
1746 /* Setting the TLS1 client and server random parameters, as well as the
1747 * MAC and encryption algorithm parameters. */
1748 data_blob.cbData = 33;
1749 data_blob.pbData = abClientSecret;
1750 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1751 ok (result, "%08x\n", GetLastError());
1752 if (!result) return;
1754 data_blob.cbData = 33;
1755 data_blob.pbData = abServerSecret;
1756 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1757 ok (result, "%08x\n", GetLastError());
1758 if (!result) return;
1760 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1761 saSChannelAlg.Algid = CALG_DES;
1762 saSChannelAlg.cBits = 64;
1763 saSChannelAlg.dwFlags = 0;
1764 saSChannelAlg.dwReserved = 0;
1765 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1766 ok (result, "%08x\n", GetLastError());
1767 if (!result) return;
1769 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1770 saSChannelAlg.Algid = CALG_MD5;
1771 saSChannelAlg.cBits = 128;
1772 saSChannelAlg.dwFlags = 0;
1773 saSChannelAlg.dwReserved = 0;
1774 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1775 ok (result, "%08x\n", GetLastError());
1776 if (!result) return;
1778 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1779 * (Keys can only be derived from hashes, not from other keys.) */
1780 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1781 ok (result, "%08x\n", GetLastError());
1782 if (!result) return;
1784 /* Deriving the server write encryption key from the master hash */
1785 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1786 ok (result, "%08x\n", GetLastError());
1787 if (!result) return;
1789 /* Encrypting some data with the server write encryption key and checking the result. */
1791 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1792 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1794 /* Second test case: Test the TLS1 pseudo random number function. */
1795 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1796 ok (result, "%08x\n", GetLastError());
1797 if (!result) return;
1799 /* Set the label and seed parameters for the random number function */
1800 data_blob.cbData = 36;
1801 data_blob.pbData = abHashedHandshakes;
1802 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1803 ok (result, "%08x\n", GetLastError());
1804 if (!result) return;
1806 data_blob.cbData = 15;
1807 data_blob.pbData = abClientFinished;
1808 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1809 ok (result, "%08x\n", GetLastError());
1810 if (!result) return;
1812 /* Generate some pseudo random bytes and check if they are correct. */
1813 dwLen = (DWORD)sizeof(abData);
1814 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1815 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1816 "%08x\n", GetLastError());
1818 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1819 * Hash some data with the HMAC. Compare results. */
1820 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1821 ok (result, "%08x\n", GetLastError());
1822 if (!result) return;
1824 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1825 ok (result, "%08x\n", GetLastError());
1826 if (!result) return;
1828 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1829 ok (result, "%08x\n", GetLastError());
1830 if (!result) return;
1832 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1833 ok (result, "%08x\n", GetLastError());
1834 if (!result) return;
1836 dwLen = (DWORD)sizeof(abMD5Hash);
1837 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1838 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1840 CryptDestroyHash(hHMAC);
1841 CryptDestroyHash(hTLS1PRF);
1842 CryptDestroyHash(hMasterHash);
1843 CryptDestroyKey(hServerWriteMACKey);
1844 CryptDestroyKey(hServerWriteKey);
1845 CryptDestroyKey(hRSAKey);
1846 CryptDestroyKey(hMasterSecret);
1847 CryptReleaseContext(hProv, 0);
1848 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1851 static void test_enum_container(void)
1853 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
1855 BOOL result, fFound = FALSE;
1857 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1858 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1859 SetLastError(0xdeadbeef);
1860 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1861 ok (result, "%08x\n", GetLastError());
1862 ok (dwBufferLen == MAX_PATH + 1 ||
1863 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
1864 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
1866 /* If the result fits into abContainerName dwBufferLen is left untouched */
1867 dwBufferLen = (DWORD)sizeof(abContainerName);
1868 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1869 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1871 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1873 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1874 dwBufferLen = (DWORD)sizeof(abContainerName);
1875 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1877 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1880 static BYTE signBlob[] = {
1881 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1882 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1883 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1884 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1885 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1886 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1887 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1888 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1889 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1890 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1891 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1892 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1893 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1894 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1895 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1896 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1897 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1898 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1899 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1900 0xb6,0x85,0x86,0x07 };
1902 static void test_null_provider(void)
1907 DWORD keySpec, dataLen,dwParam;
1908 char szName[MAX_PATH];
1910 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1911 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1912 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1913 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1914 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
1915 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
1916 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1917 CRYPT_DELETEKEYSET);
1918 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
1919 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
1920 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1921 CRYPT_DELETEKEYSET);
1922 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1923 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1924 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1925 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1926 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1928 /* Delete the default container. */
1929 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1930 /* Once you've deleted the default container you can't open it as if it
1933 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1934 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1935 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1936 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1937 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1938 CRYPT_VERIFYCONTEXT);
1939 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1940 if (!result) return;
1941 dataLen = sizeof(keySpec);
1942 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1944 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1945 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1946 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1947 * supported, you can't get the keys from this container.
1949 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1950 ok(!result && GetLastError() == NTE_NO_KEY,
1951 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1952 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1953 ok(!result && GetLastError() == NTE_NO_KEY,
1954 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1955 result = CryptReleaseContext(prov, 0);
1956 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1957 /* You can create a new default container. */
1958 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1960 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1961 /* But you still can't get the keys (until one's been generated.) */
1962 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1963 ok(!result && GetLastError() == NTE_NO_KEY,
1964 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1965 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1966 ok(!result && GetLastError() == NTE_NO_KEY,
1967 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1968 CryptReleaseContext(prov, 0);
1969 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1971 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1972 CRYPT_DELETEKEYSET);
1973 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1974 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1975 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1976 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1977 CRYPT_VERIFYCONTEXT);
1978 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1979 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1980 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1982 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1983 if (!result) return;
1984 /* Test provider parameters getter */
1985 dataLen = sizeof(dwParam);
1986 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1987 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1988 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1989 dataLen = sizeof(dwParam);
1990 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1991 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1992 "Expected 0, got 0x%08X\n",dwParam);
1993 dataLen = sizeof(dwParam);
1994 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1995 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1996 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1997 dataLen = sizeof(keySpec);
1998 SetLastError(0xdeadbeef);
1999 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2000 if (!result && GetLastError() == NTE_BAD_TYPE)
2001 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2003 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2004 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2005 /* PP_CONTAINER parameter */
2006 dataLen = sizeof(szName);
2007 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2008 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2009 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2010 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2011 /* PP_UNIQUE_CONTAINER parameter */
2012 dataLen = sizeof(szName);
2013 SetLastError(0xdeadbeef);
2014 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2015 if (!result && GetLastError() == NTE_BAD_TYPE)
2017 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2021 char container[MAX_PATH];
2023 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2024 uniquecontainer(container);
2027 ok(dataLen == strlen(container)+1, "Expected a param length of 70, got %d\n", dataLen);
2028 ok(!strcmp(container, szName), "Wrong container name : %s\n", szName);
2031 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2032 ok(!result && GetLastError() == NTE_NO_KEY,
2033 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2034 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2035 ok(!result && GetLastError() == NTE_NO_KEY,
2036 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2038 /* Importing a key exchange blob.. */
2039 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2041 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2042 CryptDestroyKey(key);
2043 /* allows access to the key exchange key.. */
2044 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2045 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2046 CryptDestroyKey(key);
2047 /* but not to the private key. */
2048 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2049 ok(!result && GetLastError() == NTE_NO_KEY,
2050 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2051 CryptReleaseContext(prov, 0);
2052 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2053 CRYPT_DELETEKEYSET);
2055 /* Whereas importing a sign blob.. */
2056 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2058 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2059 if (!result) return;
2060 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2061 ok(result, "CryptGenKey failed: %08x\n", GetLastError());
2062 CryptDestroyKey(key);
2063 /* doesn't allow access to the key exchange key.. */
2064 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2065 ok(!result && GetLastError() == NTE_NO_KEY,
2066 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2067 /* but does to the private key. */
2068 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2069 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2070 CryptDestroyKey(key);
2071 CryptReleaseContext(prov, 0);
2073 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2074 CRYPT_DELETEKEYSET);
2077 /* test for the bug in accessing the user key in a container
2079 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2081 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2082 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2083 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2084 CryptDestroyKey(key);
2085 CryptReleaseContext(prov,0);
2086 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2087 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2088 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2089 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2090 CryptDestroyKey(key);
2091 CryptReleaseContext(prov, 0);
2093 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2094 CRYPT_DELETEKEYSET);
2096 /* test the machine key set */
2097 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2098 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2099 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2100 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2101 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2102 CryptReleaseContext(prov, 0);
2103 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2104 CRYPT_MACHINE_KEYSET);
2105 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2106 CryptReleaseContext(prov,0);
2107 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2108 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2109 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2111 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2112 CRYPT_MACHINE_KEYSET);
2113 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2114 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2118 static void test_key_permissions(void)
2120 HCRYPTKEY hKey1, hKey2;
2124 /* Create keys that are exportable */
2125 if (!init_base_environment(CRYPT_EXPORTABLE))
2128 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2129 ok (result, "%08x\n", GetLastError());
2130 if (!result) return;
2133 dwLen = sizeof(DWORD);
2134 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2135 ok(result, "%08x\n", GetLastError());
2137 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT),
2138 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2139 " got %08x\n", dwVal);
2141 /* The key exchange key's public key may be exported.. */
2142 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2143 ok(result, "%08x\n", GetLastError());
2144 /* and its private key may be too. */
2145 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2146 ok(result, "%08x\n", GetLastError());
2147 /* Turning off the key's export permissions is "allowed".. */
2148 dwVal &= ~CRYPT_EXPORT;
2149 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2150 ok(result, "%08x\n", GetLastError());
2151 /* but it has no effect. */
2153 dwLen = sizeof(DWORD);
2154 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2155 ok(result, "%08x\n", GetLastError());
2157 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT),
2158 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2159 " got %08x\n", dwVal);
2160 /* Thus, changing the export flag of the key doesn't affect whether the key
2163 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2164 ok(result, "%08x\n", GetLastError());
2166 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2167 ok (result, "%08x\n", GetLastError());
2169 /* A subsequent get of the same key, into a different handle, also doesn't
2170 * show that the permissions have been changed.
2173 dwLen = sizeof(DWORD);
2174 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2175 ok(result, "%08x\n", GetLastError());
2177 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT),
2178 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2179 " got %08x\n", dwVal);
2181 CryptDestroyKey(hKey2);
2182 CryptDestroyKey(hKey1);
2184 clean_up_base_environment();
2187 static void test_key_initialization(void)
2190 HCRYPTPROV prov1, prov2;
2191 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2193 static BYTE abSessionKey[148] = {
2194 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2195 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2196 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2197 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2198 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2199 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2200 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2201 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2202 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2203 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2204 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2205 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2206 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2207 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2208 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2209 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2210 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2211 0x04, 0x8c, 0x49, 0x92
2214 /* Like init_base_environment, but doesn't generate new keys, as they'll
2215 * be imported instead.
2217 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2219 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2221 ok(result, "%08x\n", GetLastError());
2223 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2224 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2226 dwLen = (DWORD)sizeof(abSessionKey);
2227 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2228 ok(result, "%08x\n", GetLastError());
2230 /* Once the key has been imported, subsequently acquiring a context with
2231 * the same name will allow retrieving the key.
2233 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2234 ok(result, "%08x\n", GetLastError());
2235 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2236 ok(result, "%08x\n", GetLastError());
2237 if (result) CryptDestroyKey(hKey);
2238 CryptReleaseContext(prov2, 0);
2240 CryptDestroyKey(hSessionKey);
2241 CryptDestroyKey(hKeyExchangeKey);
2242 CryptReleaseContext(prov1, 0);
2243 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2244 CRYPT_DELETEKEYSET);
2249 if (!init_base_environment(0))
2261 test_block_cipher_modes();
2262 test_import_private();
2263 test_verify_signature();
2265 test_import_export();
2266 test_enum_container();
2267 clean_up_base_environment();
2268 test_key_permissions();
2269 test_key_initialization();
2270 test_schannel_provider();
2271 test_null_provider();
2272 if (!init_aes_environment())
2277 clean_up_aes_environment();