2 * Unit tests for rsaenh functions
4 * Copyright (c) 2004 Michael Jung
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
29 static HCRYPTPROV hProv;
30 static const char szContainer[] = "winetest";
31 static const unsigned char pbData[] = "Wine rocks totally!";
32 static const char szProvider[] = MS_ENHANCED_PROV_A;
34 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
37 static void trace_hex(BYTE *pbData, DWORD dwLen) {
41 for (i = 0; i < dwLen-7; i+=8) {
42 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
43 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
44 pbData[i+6], pbData[i+7]);
47 for (j=0; i<dwLen; j++,i++) {
48 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
54 static int init_environment(void)
59 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
61 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
63 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
64 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
66 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
68 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
69 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
70 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
72 ok(result, "%08x\n", GetLastError());
73 if (!result) return 0;
74 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
75 ok(result, "%08x\n", GetLastError());
76 if (result) CryptDestroyKey(hKey);
77 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
78 ok(result, "%08x\n", GetLastError());
79 if (result) CryptDestroyKey(hKey);
84 static void clean_up_environment(void)
88 result = CryptReleaseContext(hProv, 1);
89 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
91 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
94 static void test_prov(void)
99 dwLen = (DWORD)sizeof(DWORD);
100 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
101 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
103 dwLen = (DWORD)sizeof(DWORD);
104 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
105 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
108 static void test_gen_random(void)
111 BYTE rnd1[16], rnd2[16];
113 memset(rnd1, 0, sizeof(rnd1));
114 memset(rnd2, 0, sizeof(rnd2));
116 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
117 if (!result && GetLastError() == NTE_FAIL) {
118 /* rsaenh compiled without OpenSSL */
122 ok(result, "%08x\n", GetLastError());
124 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
125 ok(result, "%08x\n", GetLastError());
127 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
130 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
134 unsigned char pbData[2000];
137 *phKey = (HCRYPTKEY)NULL;
138 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
139 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
141 /* rsaenh compiled without OpenSSL */
142 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
145 ok(result, "%08x\n", GetLastError());
146 if (!result) return FALSE;
147 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
148 ok(result, "%08x\n", GetLastError());
149 if (!result) return FALSE;
150 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
151 ok(result, "%08x\n", GetLastError());
152 if (!result) return FALSE;
154 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
155 ok(result, "%08x\n", GetLastError());
156 CryptDestroyHash(hHash);
160 static void test_hashes(void)
162 static const unsigned char md2hash[16] = {
163 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
164 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
165 static const unsigned char md4hash[16] = {
166 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
167 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
168 static const unsigned char md5hash[16] = {
169 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
170 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
171 static const unsigned char sha1hash[20] = {
172 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
173 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
174 unsigned char pbData[2048];
176 HCRYPTHASH hHash, hHashClone;
177 BYTE pbHashValue[36];
181 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
184 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
186 /* rsaenh compiled without OpenSSL */
187 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
189 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
190 ok(result, "%08x\n", GetLastError());
193 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
194 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
197 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
198 ok(result, "%08x\n", GetLastError());
200 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
202 result = CryptDestroyHash(hHash);
203 ok(result, "%08x\n", GetLastError());
207 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
208 ok(result, "%08x\n", GetLastError());
210 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
211 ok(result, "%08x\n", GetLastError());
214 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
215 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
218 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
219 ok(result, "%08x\n", GetLastError());
221 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
223 result = CryptDestroyHash(hHash);
224 ok(result, "%08x\n", GetLastError());
227 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
228 ok(result, "%08x\n", GetLastError());
230 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
231 ok(result, "%08x\n", GetLastError());
234 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
235 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
238 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
239 ok(result, "%08x\n", GetLastError());
241 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
243 result = CryptDestroyHash(hHash);
244 ok(result, "%08x\n", GetLastError());
247 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
248 ok(result, "%08x\n", GetLastError());
250 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
251 ok(result, "%08x\n", GetLastError());
253 if(pCryptDuplicateHash) {
254 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
255 ok(result, "%08x\n", GetLastError());
257 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
258 ok(result, "%08x\n", GetLastError());
261 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
262 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
265 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
266 ok(result, "%08x\n", GetLastError());
268 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
270 result = CryptDestroyHash(hHashClone);
271 ok(result, "%08x\n", GetLastError());
274 result = CryptDestroyHash(hHash);
275 ok(result, "%08x\n", GetLastError());
278 static void test_block_cipher_modes(void)
280 static const BYTE plain[23] = {
281 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
282 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
283 static const BYTE ecb[24] = {
284 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
285 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
286 static const BYTE cbc[24] = {
287 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
288 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
289 static const BYTE cfb[24] = {
290 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
291 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
297 result = derive_key(CALG_RC2, &hKey, 40);
300 memcpy(abData, plain, sizeof(abData));
302 dwMode = CRYPT_MODE_ECB;
303 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
304 ok(result, "%08x\n", GetLastError());
307 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
308 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
309 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
311 SetLastError(ERROR_SUCCESS);
313 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
314 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
315 "%08x, dwLen: %d\n", GetLastError(), dwLen);
317 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
318 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
319 "%08x, dwLen: %d\n", GetLastError(), dwLen);
321 dwMode = CRYPT_MODE_CBC;
322 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
323 ok(result, "%08x\n", GetLastError());
326 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
327 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
328 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
331 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
332 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
333 "%08x, dwLen: %d\n", GetLastError(), dwLen);
335 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
336 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
337 "%08x, dwLen: %d\n", GetLastError(), dwLen);
339 dwMode = CRYPT_MODE_CFB;
340 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
341 ok(result, "%08x\n", GetLastError());
344 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
345 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
348 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
349 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
350 "%08x, dwLen: %d\n", GetLastError(), dwLen);
353 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
354 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
357 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
358 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
359 "%08x, dwLen: %d\n", GetLastError(), dwLen);
361 dwMode = CRYPT_MODE_OFB;
362 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
363 ok(result, "%08x\n", GetLastError());
366 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
367 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
370 static void test_3des112(void)
375 unsigned char pbData[16];
378 result = derive_key(CALG_3DES_112, &hKey, 0);
380 /* rsaenh compiled without OpenSSL */
381 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
385 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
388 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
389 ok(result, "%08x\n", GetLastError());
391 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
392 ok(result, "%08x\n", GetLastError());
394 result = CryptDestroyKey(hKey);
395 ok(result, "%08x\n", GetLastError());
398 static void test_des(void)
403 unsigned char pbData[16];
406 result = derive_key(CALG_DES, &hKey, 56);
408 /* rsaenh compiled without OpenSSL */
409 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
413 dwMode = CRYPT_MODE_ECB;
414 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
415 ok(result, "%08x\n", GetLastError());
417 dwLen = sizeof(DWORD);
418 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
419 ok(result, "%08x\n", GetLastError());
421 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
424 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
425 ok(result, "%08x\n", GetLastError());
427 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
428 ok(result, "%08x\n", GetLastError());
430 result = CryptDestroyKey(hKey);
431 ok(result, "%08x\n", GetLastError());
434 static void test_3des(void)
439 unsigned char pbData[16];
440 static const BYTE des3[16] = {
441 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
442 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
445 result = derive_key(CALG_3DES, &hKey, 0);
448 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
451 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
452 ok(result, "%08x\n", GetLastError());
454 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
456 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
457 ok(result, "%08x\n", GetLastError());
459 result = CryptDestroyKey(hKey);
460 ok(result, "%08x\n", GetLastError());
463 static void test_rc2(void)
465 static const BYTE rc2encrypted[16] = {
466 0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
467 0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
471 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
473 unsigned char pbData[2000], pbHashValue[16];
476 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
479 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
481 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
483 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
484 ok(result, "%08x\n", GetLastError());
487 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
488 ok(result, "%08x\n", GetLastError());
490 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
491 ok(result, "%08x\n", GetLastError());
493 dwLen = sizeof(DWORD);
494 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
495 ok(result, "%08x\n", GetLastError());
497 dwMode = CRYPT_MODE_CBC;
498 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
499 ok(result, "%08x\n", GetLastError());
501 dwLen = sizeof(DWORD);
502 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
503 ok(result, "%08x\n", GetLastError());
505 dwLen = sizeof(DWORD);
506 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
507 ok(result, "%08x\n", GetLastError());
509 dwLen = sizeof(DWORD);
510 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
511 ok(result, "%08x\n", GetLastError());
513 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
514 ok(result, "%08x\n", GetLastError());
515 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
516 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
517 HeapFree(GetProcessHeap(), 0, pbTemp);
519 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
520 ok(result, "%08x\n", GetLastError());
521 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
522 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
523 HeapFree(GetProcessHeap(), 0, pbTemp);
525 dwLen = sizeof(DWORD);
526 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
528 result = CryptDestroyHash(hHash);
529 ok(result, "%08x\n", GetLastError());
532 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
533 ok(result, "%08x\n", GetLastError());
535 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
537 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
538 ok(result, "%08x\n", GetLastError());
539 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
540 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
541 HeapFree(GetProcessHeap(), 0, pbTemp);
543 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
544 ok(result, "%08x\n", GetLastError());
546 result = CryptDestroyKey(hKey);
547 ok(result, "%08x\n", GetLastError());
551 static void test_rc4(void)
553 static const BYTE rc4[16] = {
554 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
555 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
559 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
560 unsigned char pbData[2000], *pbTemp;
561 unsigned char pszBuffer[256];
564 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
567 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
569 /* rsaenh compiled without OpenSSL */
570 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
572 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
573 ok(result, "%08x\n", GetLastError());
576 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
577 ok(result, "%08x\n", GetLastError());
579 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
580 ok(result, "%08x\n", GetLastError());
582 dwLen = sizeof(DWORD);
583 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
584 ok(result, "%08x\n", GetLastError());
586 dwLen = sizeof(DWORD);
587 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
588 ok(result, "%08x\n", GetLastError());
590 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
591 ok(result, "%08x\n", GetLastError());
592 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
593 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
594 HeapFree(GetProcessHeap(), 0, pbTemp);
596 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
597 ok(result, "%08x\n", GetLastError());
598 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
599 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
600 HeapFree(GetProcessHeap(), 0, pbTemp);
602 dwLen = sizeof(DWORD);
603 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
605 result = CryptDestroyHash(hHash);
606 ok(result, "%08x\n", GetLastError());
609 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
610 ok(result, "%08x\n", GetLastError());
612 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
613 ok(result, "%08x\n", GetLastError());
615 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
617 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
618 ok(result, "%08x\n", GetLastError());
620 result = CryptDestroyKey(hKey);
621 ok(result, "%08x\n", GetLastError());
625 static void test_hmac(void) {
629 /* Using CALG_MD2 here fails on Windows 2003, why ? */
630 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
633 static const BYTE hmac[16] = {
634 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
635 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
638 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
640 if (!derive_key(CALG_RC2, &hKey, 56)) return;
642 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
643 ok(result, "%08x\n", GetLastError());
646 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
647 ok(result, "%08x\n", GetLastError());
649 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
650 ok(result, "%08x\n", GetLastError());
652 dwLen = sizeof(abData)/sizeof(BYTE);
653 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
654 ok(result, "%08x\n", GetLastError());
656 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
658 result = CryptDestroyHash(hHash);
659 ok(result, "%08x\n", GetLastError());
661 result = CryptDestroyKey(hKey);
662 ok(result, "%08x\n", GetLastError());
665 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
666 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
669 static void test_mac(void) {
674 BYTE abData[256], abEnc[264];
675 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
678 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
679 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
681 if (!derive_key(CALG_RC2, &hKey, 56)) return;
684 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
685 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
687 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
688 ok(result, "%08x\n", GetLastError());
691 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
692 ok(result, "%08x\n", GetLastError());
694 dwLen = sizeof(abData)/sizeof(BYTE);
695 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
696 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
698 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
700 result = CryptDestroyHash(hHash);
701 ok(result, "%08x\n", GetLastError());
703 result = CryptDestroyKey(hKey);
704 ok(result, "%08x\n", GetLastError());
707 if (!derive_key(CALG_RC4, &hKey, 56)) return;
709 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
710 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
712 result = CryptDestroyKey(hKey);
713 ok(result, "%08x\n", GetLastError());
716 static BYTE abPlainPrivateKey[596] = {
717 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
718 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
719 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
720 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
721 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
722 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
723 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
724 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
725 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
726 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
727 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
728 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
729 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
730 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
731 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
732 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
733 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
734 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
735 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
736 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
737 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
738 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
739 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
740 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
741 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
742 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
743 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
744 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
745 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
746 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
747 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
748 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
749 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
750 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
751 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
752 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
753 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
754 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
755 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
756 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
757 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
758 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
759 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
760 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
761 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
762 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
763 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
764 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
765 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
766 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
767 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
768 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
769 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
770 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
771 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
772 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
773 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
774 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
775 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
776 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
777 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
778 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
779 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
780 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
781 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
782 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
783 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
784 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
785 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
786 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
787 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
788 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
789 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
790 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
791 0xf2, 0x5d, 0x58, 0x07
794 static void test_import_private(void)
797 HCRYPTKEY hKeyExchangeKey, hSessionKey;
799 static BYTE abSessionKey[148] = {
800 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
801 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
802 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
803 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
804 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
805 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
806 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
807 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
808 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
809 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
810 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
811 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
812 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
813 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
814 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
815 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
816 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
817 0x04, 0x8c, 0x49, 0x92
819 static BYTE abEncryptedMessage[12] = {
820 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
821 0x1c, 0xfd, 0xde, 0x71
824 dwLen = (DWORD)sizeof(abPlainPrivateKey);
825 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
827 /* rsaenh compiled without OpenSSL */
828 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
832 dwLen = (DWORD)sizeof(abSessionKey);
833 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
834 ok(result, "%08x\n", GetLastError());
837 dwLen = (DWORD)sizeof(abEncryptedMessage);
838 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
839 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
840 "%08x, len: %d\n", GetLastError(), dwLen);
842 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
844 dwLen = (DWORD)sizeof(abSessionKey);
845 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
846 ok(result, "%08x\n", GetLastError());
849 dwLen = (DWORD)sizeof(abSessionKey);
850 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
851 ok(result, "%08x\n", GetLastError());
855 static void test_verify_signature(void) {
857 HCRYPTKEY hPubSignKey;
858 BYTE abData[] = "Wine rocks!";
860 BYTE abPubKey[148] = {
861 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
862 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
863 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
864 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
865 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
866 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
867 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
868 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
869 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
870 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
871 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
872 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
873 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
874 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
875 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
876 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
877 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
878 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
879 0xe1, 0x21, 0x50, 0xac
881 /* md2 with hash oid */
882 BYTE abSignatureMD2[128] = {
883 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
884 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
885 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
886 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
887 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
888 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
889 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
890 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
891 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
892 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
893 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
894 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
895 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
896 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
897 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
898 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
900 /* md2 without hash oid */
901 BYTE abSignatureMD2NoOID[128] = {
902 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
903 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
904 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
905 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
906 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
907 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
908 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
909 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
910 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
911 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
912 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
913 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
914 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
915 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
916 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
917 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
919 /* md4 with hash oid */
920 BYTE abSignatureMD4[128] = {
921 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
922 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
923 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
924 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
925 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
926 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
927 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
928 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
929 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
930 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
931 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
932 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
933 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
934 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
935 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
936 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
938 /* md4 without hash oid */
939 BYTE abSignatureMD4NoOID[128] = {
940 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
941 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
942 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
943 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
944 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
945 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
946 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
947 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
948 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
949 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
950 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
951 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
952 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
953 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
954 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
955 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
957 /* md5 with hash oid */
958 BYTE abSignatureMD5[128] = {
959 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
960 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
961 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
962 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
963 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
964 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
965 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
966 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
967 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
968 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
969 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
970 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
971 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
972 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
973 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
974 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
976 /* md5 without hash oid */
977 BYTE abSignatureMD5NoOID[128] = {
978 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
979 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
980 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
981 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
982 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
983 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
984 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
985 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
986 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
987 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
988 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
989 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
990 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
991 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
992 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
993 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
995 /* sha with hash oid */
996 BYTE abSignatureSHA[128] = {
997 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
998 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
999 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1000 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1001 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1002 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1003 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1004 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1005 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1006 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1007 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1008 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1009 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1010 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1011 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1012 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1014 /* sha without hash oid */
1015 BYTE abSignatureSHANoOID[128] = {
1016 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1017 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1018 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1019 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1020 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1021 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1022 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1023 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1024 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1025 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1026 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1027 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1028 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1029 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1030 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1031 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1034 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1035 ok(result, "%08x\n", GetLastError());
1036 if (!result) return;
1038 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1039 ok(result, "%08x\n", GetLastError());
1040 if (!result) return;
1042 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1043 ok(result, "%08x\n", GetLastError());
1044 if (!result) return;
1046 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1047 ok(result, "%08x\n", GetLastError());
1048 if (!result) return;
1050 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1051 ok(result, "%08x\n", GetLastError());
1052 if (!result) return;
1054 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1055 * the OID at all. */
1056 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1057 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1058 if (result) return;*/
1060 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1061 ok(result, "%08x\n", GetLastError());
1062 if (!result) return;
1064 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1065 ok(result, "%08x\n", GetLastError());
1066 if (!result) return;
1068 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1069 ok(result, "%08x\n", GetLastError());
1070 if (!result) return;
1072 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1073 ok(result, "%08x\n", GetLastError());
1074 if (!result) return;
1076 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1077 ok(result, "%08x\n", GetLastError());
1078 if (!result) return;
1080 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1081 ok(result, "%08x\n", GetLastError());
1082 if (!result) return;
1084 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1085 ok(result, "%08x\n", GetLastError());
1086 if (!result) return;
1088 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1089 ok(result, "%08x\n", GetLastError());
1090 if (!result) return;
1092 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1093 ok(result, "%08x\n", GetLastError());
1094 if (!result) return;
1096 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1097 ok(result, "%08x\n", GetLastError());
1098 if (!result) return;
1100 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1101 ok(result, "%08x\n", GetLastError());
1102 if (!result) return;
1104 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1105 ok(result, "%08x\n", GetLastError());
1106 if (!result) return;
1109 static void test_rsa_encrypt(void)
1112 BYTE abData[2048] = "Wine rocks!";
1116 /* It is allowed to use the key exchange key for encryption/decryption */
1117 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1118 ok (result, "%08x\n", GetLastError());
1119 if (!result) return;
1122 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1123 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1124 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1126 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1127 ok (result, "%08x\n", GetLastError());
1128 if (!result) return;
1130 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1131 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1133 CryptDestroyKey(hRSAKey);
1135 /* It is not allowed to use the signature key for encryption/decryption */
1136 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1137 ok (result, "%08x\n", GetLastError());
1138 if (!result) return;
1141 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1142 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1144 CryptDestroyKey(hRSAKey);
1147 static void test_import_export(void)
1149 DWORD dwLen, dwDataLen;
1150 HCRYPTKEY hPublicKey;
1153 BYTE emptyKey[2048];
1154 static BYTE abPlainPublicKey[84] = {
1155 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1156 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1157 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1158 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1159 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1160 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1161 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1162 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1163 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1164 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1165 0x11, 0x11, 0x11, 0x11
1169 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1170 ok(result, "failed to import the public key\n");
1172 dwDataLen=sizeof(algID);
1173 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1174 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1175 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1177 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1178 ok(result, "failed to export the fresh imported public key\n");
1179 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1180 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1183 static void test_schannel_provider(void)
1186 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1187 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1190 SCHANNEL_ALG saSChannelAlg;
1191 CRYPT_DATA_BLOB data_blob;
1192 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1193 BYTE abPlainPrivateKey[596] = {
1194 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1195 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1196 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1197 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1198 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1199 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1200 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1201 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1202 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1203 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1204 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1205 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1206 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1207 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1208 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1209 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1210 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1211 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1212 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1213 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1214 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1215 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1216 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1217 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1218 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1219 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1220 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1221 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1222 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1223 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1224 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1225 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1226 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1227 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1228 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1229 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1230 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1231 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1232 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1233 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1234 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1235 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1236 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1237 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1238 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1239 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1240 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1241 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1242 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1243 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1244 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1245 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1246 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1247 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1248 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1249 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1250 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1251 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1252 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1253 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1254 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1255 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1256 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1257 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1258 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1259 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1260 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1261 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1262 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1263 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1264 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1265 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1266 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1267 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1268 0xf2, 0x5d, 0x58, 0x07
1270 BYTE abTLS1Master[140] = {
1271 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1272 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1273 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1274 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1275 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1276 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1277 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1278 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1279 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1280 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1281 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1282 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1283 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1284 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1285 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1286 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1287 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1288 0xd3, 0x1e, 0x82, 0xb3
1290 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1291 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1292 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1293 BYTE abClientFinished[16] = "client finished";
1294 BYTE abData[16] = "Wine rocks!";
1296 static const BYTE abEncryptedData[16] = {
1297 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1298 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1300 static const BYTE abPRF[16] = {
1301 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1302 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1304 static const BYTE abMD5[16] = {
1305 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1306 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1309 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1310 ok (result, "%08x\n", GetLastError());
1311 if (!result) return;
1313 /* To get deterministic results, we import the TLS1 master secret (which
1314 * is typically generated from a random generator). Therefore, we need
1316 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1317 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1318 ok (result, "%08x\n", GetLastError());
1319 if (!result) return;
1321 dwLen = (DWORD)sizeof(abTLS1Master);
1322 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1323 ok (result, "%08x\n", GetLastError());
1324 if (!result) return;
1326 /* Setting the TLS1 client and server random parameters, as well as the
1327 * MAC and encryption algorithm parameters. */
1328 data_blob.cbData = 33;
1329 data_blob.pbData = abClientSecret;
1330 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1331 ok (result, "%08x\n", GetLastError());
1332 if (!result) return;
1334 data_blob.cbData = 33;
1335 data_blob.pbData = abServerSecret;
1336 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1337 ok (result, "%08x\n", GetLastError());
1338 if (!result) return;
1340 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1341 saSChannelAlg.Algid = CALG_DES;
1342 saSChannelAlg.cBits = 64;
1343 saSChannelAlg.dwFlags = 0;
1344 saSChannelAlg.dwReserved = 0;
1345 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1346 ok (result, "%08x\n", GetLastError());
1347 if (!result) return;
1349 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1350 saSChannelAlg.Algid = CALG_MD5;
1351 saSChannelAlg.cBits = 128;
1352 saSChannelAlg.dwFlags = 0;
1353 saSChannelAlg.dwReserved = 0;
1354 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1355 ok (result, "%08x\n", GetLastError());
1356 if (!result) return;
1358 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1359 * (Keys can only be derived from hashes, not from other keys.) */
1360 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1361 ok (result, "%08x\n", GetLastError());
1362 if (!result) return;
1364 /* Deriving the server write encryption key from the master hash */
1365 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1366 ok (result, "%08x\n", GetLastError());
1367 if (!result) return;
1369 /* Encrypting some data with the server write encryption key and checking the result. */
1371 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1372 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1374 /* Second test case: Test the TLS1 pseudo random number function. */
1375 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1376 ok (result, "%08x\n", GetLastError());
1377 if (!result) return;
1379 /* Set the label and seed parameters for the random number function */
1380 data_blob.cbData = 36;
1381 data_blob.pbData = abHashedHandshakes;
1382 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1383 ok (result, "%08x\n", GetLastError());
1384 if (!result) return;
1386 data_blob.cbData = 15;
1387 data_blob.pbData = abClientFinished;
1388 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1389 ok (result, "%08x\n", GetLastError());
1390 if (!result) return;
1392 /* Generate some pseudo random bytes and check if they are correct. */
1393 dwLen = (DWORD)sizeof(abData);
1394 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1395 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1396 "%08x\n", GetLastError());
1398 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1399 * Hash some data with the HMAC. Compare results. */
1400 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1401 ok (result, "%08x\n", GetLastError());
1402 if (!result) return;
1404 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1405 ok (result, "%08x\n", GetLastError());
1406 if (!result) return;
1408 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1409 ok (result, "%08x\n", GetLastError());
1410 if (!result) return;
1412 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1413 ok (result, "%08x\n", GetLastError());
1414 if (!result) return;
1416 dwLen = (DWORD)sizeof(abMD5Hash);
1417 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1418 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1420 CryptDestroyHash(hHMAC);
1421 CryptDestroyHash(hTLS1PRF);
1422 CryptDestroyHash(hMasterHash);
1423 CryptDestroyKey(hServerWriteMACKey);
1424 CryptDestroyKey(hServerWriteKey);
1425 CryptDestroyKey(hRSAKey);
1426 CryptDestroyKey(hMasterSecret);
1427 CryptReleaseContext(hProv, 0);
1428 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1431 static void test_enum_container(void)
1433 BYTE abContainerName[256];
1435 BOOL result, fFound = FALSE;
1437 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1438 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1439 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1440 ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1442 /* If the result fits into abContainerName dwBufferLen is left untouched */
1443 dwBufferLen = (DWORD)sizeof(abContainerName);
1444 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1445 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1447 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1449 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1450 dwBufferLen = (DWORD)sizeof(abContainerName);
1451 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1453 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1456 static BYTE signBlob[] = {
1457 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1458 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1459 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1460 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1461 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1462 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1463 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1464 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1465 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1466 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1467 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1468 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1469 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1470 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1471 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1472 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1473 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1474 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1475 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1476 0xb6,0x85,0x86,0x07 };
1478 static void test_null_provider(void)
1483 DWORD keySpec, dataLen,dwParam;
1484 char szName[MAX_PATH];
1486 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1487 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1488 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1489 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1490 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1491 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1492 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1493 CRYPT_DELETEKEYSET);
1494 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1495 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1496 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1497 CRYPT_DELETEKEYSET);
1498 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1499 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1500 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1501 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1502 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1504 /* Delete the default container. */
1505 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1506 /* Once you've deleted the default container you can't open it as if it
1509 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1510 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1511 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1512 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1513 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1514 CRYPT_VERIFYCONTEXT);
1515 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1516 if (!result) return;
1517 dataLen = sizeof(keySpec);
1518 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1520 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1521 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1522 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1523 * supported, you can't get the keys from this container.
1525 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1526 ok(!result && GetLastError() == NTE_NO_KEY,
1527 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1528 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1529 ok(!result && GetLastError() == NTE_NO_KEY,
1530 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1531 result = CryptReleaseContext(prov, 0);
1532 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1533 /* You can create a new default container. */
1534 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1536 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1537 /* But you still can't get the keys (until one's been generated.) */
1538 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1539 ok(!result && GetLastError() == NTE_NO_KEY,
1540 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1541 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1542 ok(!result && GetLastError() == NTE_NO_KEY,
1543 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1544 CryptReleaseContext(prov, 0);
1545 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1547 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1548 CRYPT_DELETEKEYSET);
1549 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1550 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1551 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1552 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1553 CRYPT_VERIFYCONTEXT);
1554 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1555 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1556 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1558 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1559 if (!result) return;
1560 /* Test provider parameters getter */
1561 dataLen = sizeof(dwParam);
1562 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1563 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1564 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1565 dataLen = sizeof(dwParam);
1566 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1567 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1568 "Expected 0, got 0x%08X\n",dwParam);
1569 dataLen = sizeof(dwParam);
1570 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1571 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1572 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1573 dataLen = sizeof(keySpec);
1574 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1575 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1576 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1577 /* PP_CONTAINER parameter */
1578 dataLen = sizeof(szName);
1579 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1580 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1581 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1582 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1583 /* PP_UNIQUE_CONTAINER parameter */
1584 dataLen = sizeof(szName);
1585 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1586 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1587 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1588 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1589 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1590 ok(!result && GetLastError() == NTE_NO_KEY,
1591 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1592 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1593 ok(!result && GetLastError() == NTE_NO_KEY,
1594 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1596 /* Importing a key exchange blob.. */
1597 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1599 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1600 CryptDestroyKey(key);
1601 /* allows access to the key exchange key.. */
1602 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1603 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1604 CryptDestroyKey(key);
1605 /* but not to the private key. */
1606 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1607 ok(!result && GetLastError() == NTE_NO_KEY,
1608 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1609 CryptReleaseContext(prov, 0);
1610 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1611 CRYPT_DELETEKEYSET);
1613 /* Whereas importing a sign blob.. */
1614 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1616 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1617 if (!result) return;
1618 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1619 ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1620 /* doesn't allow access to the key exchange key.. */
1621 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1622 ok(!result && GetLastError() == NTE_NO_KEY,
1623 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1624 /* but does to the private key. */
1625 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1626 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1627 CryptDestroyKey(key);
1629 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1630 CRYPT_DELETEKEYSET);
1633 /* test for the bug in accessing the user key in a container
1635 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1637 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1638 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1639 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1640 CryptDestroyKey(key);
1641 CryptReleaseContext(prov,0);
1642 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1643 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1644 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1645 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1646 CryptDestroyKey(key);
1648 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1649 CRYPT_DELETEKEYSET);
1651 /* test the machine key set */
1652 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1653 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1654 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1655 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1656 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1657 CryptReleaseContext(prov, 0);
1658 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1659 CRYPT_MACHINE_KEYSET);
1660 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1661 CryptReleaseContext(prov,0);
1662 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1663 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1664 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1666 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1667 CRYPT_MACHINE_KEYSET);
1668 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1669 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1675 if (!init_environment())
1687 test_block_cipher_modes();
1688 test_import_private();
1689 test_verify_signature();
1691 test_import_export();
1692 test_enum_container();
1693 clean_up_environment();
1694 test_schannel_provider();
1695 test_null_provider();