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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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;
35 static void trace_hex(BYTE *pbData, DWORD dwLen) {
39 for (i = 0; i < dwLen-7; i+=8) {
40 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
41 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
42 pbData[i+6], pbData[i+7]);
45 for (j=0; i<dwLen; j++,i++) {
46 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
52 static int init_environment(void)
57 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
59 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
60 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08lx\n", result, GetLastError());
62 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
64 ok(GetLastError()==NTE_BAD_KEYSET, "%08lx\n", GetLastError());
65 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
66 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
68 ok(result, "%08lx\n", GetLastError());
69 if (!result) return 0;
70 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
71 ok(result, "%08lx\n", GetLastError());
72 if (result) CryptDestroyKey(hKey);
73 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
74 ok(result, "%08lx\n", GetLastError());
75 if (result) CryptDestroyKey(hKey);
80 static void clean_up_environment(void)
84 result = CryptReleaseContext(hProv, 1);
85 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08lx\n", GetLastError());
87 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
90 static void test_prov()
95 dwLen = (DWORD)sizeof(DWORD);
96 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
97 ok(result && dwInc==8, "%08lx, %ld\n", GetLastError(), dwInc);
99 dwLen = (DWORD)sizeof(DWORD);
100 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
101 ok(result && dwInc==8, "%08lx, %ld\n", GetLastError(), dwInc);
104 static void test_gen_random()
107 BYTE rnd1[16], rnd2[16];
109 memset(rnd1, 0, sizeof(rnd1));
110 memset(rnd2, 0, sizeof(rnd2));
112 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
113 if (!result && GetLastError() == NTE_FAIL) {
114 /* rsaenh compiled without OpenSSL */
118 ok(result, "%08lx\n", GetLastError());
120 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
121 ok(result, "%08lx\n", GetLastError());
123 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
126 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
130 unsigned char pbData[2000];
133 *phKey = (HCRYPTKEY)NULL;
134 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
135 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
137 /* rsaenh compiled without OpenSSL */
138 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
141 ok(result, "%08lx\n", GetLastError());
142 if (!result) return FALSE;
143 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
144 ok(result, "%08lx\n", GetLastError());
145 if (!result) return FALSE;
146 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
147 ok(result, "%08lx\n", GetLastError());
148 if (!result) return FALSE;
150 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
151 ok(result, "%08lx\n", GetLastError());
152 CryptDestroyHash(hHash);
156 static void test_hashes(void)
158 static const unsigned char md2hash[16] = {
159 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
160 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
161 static const unsigned char md4hash[16] = {
162 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
163 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
164 static const unsigned char md5hash[16] = {
165 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
166 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
167 static const unsigned char sha1hash[20] = {
168 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
169 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
170 unsigned char pbData[2048];
172 HCRYPTHASH hHash, hHashClone;
173 BYTE pbHashValue[36];
177 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
180 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
182 /* rsaenh compiled without OpenSSL */
183 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
185 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
186 ok(result, "%08lx\n", GetLastError());
189 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
190 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
193 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
194 ok(result, "%08lx\n", GetLastError());
196 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
198 result = CryptDestroyHash(hHash);
199 ok(result, "%08lx\n", GetLastError());
203 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
204 ok(result, "%08lx\n", GetLastError());
206 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
207 ok(result, "%08lx\n", GetLastError());
210 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
211 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
214 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
215 ok(result, "%08lx\n", GetLastError());
217 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
219 result = CryptDestroyHash(hHash);
220 ok(result, "%08lx\n", GetLastError());
223 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
224 ok(result, "%08lx\n", GetLastError());
226 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
227 ok(result, "%08lx\n", GetLastError());
230 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
231 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
234 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
235 ok(result, "%08lx\n", GetLastError());
237 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
239 result = CryptDestroyHash(hHash);
240 ok(result, "%08lx\n", GetLastError());
243 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
244 ok(result, "%08lx\n", GetLastError());
246 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
247 ok(result, "%08lx\n", GetLastError());
249 result = CryptDuplicateHash(hHash, 0, 0, &hHashClone);
250 ok(result, "%08lx\n", GetLastError());
252 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
253 ok(result, "%08lx\n", GetLastError());
256 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
257 ok(result && (hashlen == 20), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
260 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
261 ok(result, "%08lx\n", GetLastError());
263 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
265 result = CryptDestroyHash(hHashClone);
266 ok(result, "%08lx\n", GetLastError());
268 result = CryptDestroyHash(hHash);
269 ok(result, "%08lx\n", GetLastError());
272 static void test_block_cipher_modes()
274 static const BYTE plain[23] = {
275 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
276 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
277 static const BYTE ecb[24] = {
278 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
279 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
280 static const BYTE cbc[24] = {
281 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
282 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
283 static const BYTE cfb[24] = {
284 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
285 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
291 result = derive_key(CALG_RC2, &hKey, 40);
294 memcpy(abData, plain, sizeof(abData));
296 dwMode = CRYPT_MODE_ECB;
297 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
298 ok(result, "%08lx\n", GetLastError());
300 SetLastError(ERROR_SUCCESS);
302 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
303 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
304 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
306 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
307 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
308 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
310 dwMode = CRYPT_MODE_CBC;
311 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
312 ok(result, "%08lx\n", GetLastError());
315 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
316 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
317 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
319 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
320 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
321 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
323 dwMode = CRYPT_MODE_CFB;
324 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
325 ok(result, "%08lx\n", GetLastError());
328 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
329 ok(result && dwLen == 16, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
332 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
333 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
334 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
337 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
338 ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
341 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
342 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
343 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
345 dwMode = CRYPT_MODE_OFB;
346 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
347 ok(result, "%08lx\n", GetLastError());
350 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
351 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
354 static void test_3des112()
359 unsigned char pbData[16];
362 result = derive_key(CALG_3DES_112, &hKey, 0);
364 /* rsaenh compiled without OpenSSL */
365 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
369 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
372 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
373 ok(result, "%08lx\n", GetLastError());
375 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
376 ok(result, "%08lx\n", GetLastError());
378 result = CryptDestroyKey(hKey);
379 ok(result, "%08lx\n", GetLastError());
382 static void test_des()
387 unsigned char pbData[16];
390 result = derive_key(CALG_DES, &hKey, 56);
392 /* rsaenh compiled without OpenSSL */
393 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
397 dwMode = CRYPT_MODE_ECB;
398 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
399 ok(result, "%08lx\n", GetLastError());
401 dwLen = sizeof(DWORD);
402 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
403 ok(result, "%08lx\n", GetLastError());
405 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
408 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
409 ok(result, "%08lx\n", GetLastError());
411 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
412 ok(result, "%08lx\n", GetLastError());
414 result = CryptDestroyKey(hKey);
415 ok(result, "%08lx\n", GetLastError());
418 static void test_3des()
423 unsigned char pbData[16];
424 static const BYTE des3[16] = {
425 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
426 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
429 result = derive_key(CALG_3DES, &hKey, 0);
432 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
435 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
436 ok(result, "%08lx\n", GetLastError());
438 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
440 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
441 ok(result, "%08lx\n", GetLastError());
443 result = CryptDestroyKey(hKey);
444 ok(result, "%08lx\n", GetLastError());
447 static void test_rc2()
449 static const BYTE rc2encrypted[16] = {
450 0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
451 0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
455 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
457 unsigned char pbData[2000], pbHashValue[16];
460 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
463 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
465 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
467 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
468 ok(result, "%08lx\n", GetLastError());
471 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
472 ok(result, "%08lx\n", GetLastError());
474 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
475 ok(result, "%08lx\n", GetLastError());
477 dwLen = sizeof(DWORD);
478 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
479 ok(result, "%08lx\n", GetLastError());
481 dwMode = CRYPT_MODE_CBC;
482 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
483 ok(result, "%08lx\n", GetLastError());
485 dwLen = sizeof(DWORD);
486 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
487 ok(result, "%08lx\n", GetLastError());
489 dwLen = sizeof(DWORD);
490 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
491 ok(result, "%08lx\n", GetLastError());
493 dwLen = sizeof(DWORD);
494 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
495 ok(result, "%08lx\n", GetLastError());
497 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
498 ok(result, "%08lx\n", GetLastError());
499 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
500 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
501 HeapFree(GetProcessHeap(), 0, pbTemp);
503 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
504 ok(result, "%08lx\n", GetLastError());
505 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
506 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
507 HeapFree(GetProcessHeap(), 0, pbTemp);
509 dwLen = sizeof(DWORD);
510 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
512 result = CryptDestroyHash(hHash);
513 ok(result, "%08lx\n", GetLastError());
516 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
517 ok(result, "%08lx\n", GetLastError());
519 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
521 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
522 ok(result, "%08lx\n", GetLastError());
523 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
524 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
525 HeapFree(GetProcessHeap(), 0, pbTemp);
527 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
528 ok(result, "%08lx\n", GetLastError());
530 result = CryptDestroyKey(hKey);
531 ok(result, "%08lx\n", GetLastError());
535 static void test_rc4()
537 static const BYTE rc4[16] = {
538 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
539 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
543 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
544 unsigned char pbData[2000], *pbTemp;
545 unsigned char pszBuffer[256];
548 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
551 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
553 /* rsaenh compiled without OpenSSL */
554 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
556 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
557 ok(result, "%08lx\n", GetLastError());
560 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
561 ok(result, "%08lx\n", GetLastError());
563 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
564 ok(result, "%08lx\n", GetLastError());
566 dwLen = sizeof(DWORD);
567 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
568 ok(result, "%08lx\n", GetLastError());
570 dwLen = sizeof(DWORD);
571 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
572 ok(result, "%08lx\n", GetLastError());
574 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
575 ok(result, "%08lx\n", GetLastError());
576 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
577 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
578 HeapFree(GetProcessHeap(), 0, pbTemp);
580 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
581 ok(result, "%08lx\n", GetLastError());
582 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
583 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
584 HeapFree(GetProcessHeap(), 0, pbTemp);
586 dwLen = sizeof(DWORD);
587 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
589 result = CryptDestroyHash(hHash);
590 ok(result, "%08lx\n", GetLastError());
593 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
594 ok(result, "%08lx\n", GetLastError());
596 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
598 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
599 ok(result, "%08lx\n", GetLastError());
601 result = CryptDestroyKey(hKey);
602 ok(result, "%08lx\n", GetLastError());
606 static void test_hmac() {
610 HMAC_INFO hmacInfo = { CALG_MD2, NULL, 0, NULL, 0 };
613 static const BYTE hmac[16] = {
614 0xfd, 0x16, 0xb5, 0xb6, 0x13, 0x1c, 0x2b, 0xd6,
615 0x0a, 0xc7, 0xae, 0x92, 0x76, 0xa3, 0x05, 0x71 };
618 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
620 if (!derive_key(CALG_RC2, &hKey, 56)) return;
622 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
623 ok(result, "%08lx\n", GetLastError());
626 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
627 ok(result, "%08lx\n", GetLastError());
629 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
630 ok(result, "%08lx\n", GetLastError());
632 dwLen = sizeof(abData)/sizeof(BYTE);
633 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
634 ok(result, "%08lx\n", GetLastError());
636 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
638 result = CryptDestroyHash(hHash);
639 ok(result, "%08lx\n", GetLastError());
641 result = CryptDestroyKey(hKey);
642 ok(result, "%08lx\n", GetLastError());
645 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
646 ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
649 static void test_mac() {
654 BYTE abData[256], abEnc[264];
655 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
658 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
659 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
661 if (!derive_key(CALG_RC2, &hKey, 56)) return;
664 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
665 ok (result && dwLen == 264, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
667 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
668 ok(result, "%08lx\n", GetLastError());
671 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
672 ok(result, "%08lx\n", GetLastError());
674 dwLen = sizeof(abData)/sizeof(BYTE);
675 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
676 ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
678 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
680 result = CryptDestroyHash(hHash);
681 ok(result, "%08lx\n", GetLastError());
683 result = CryptDestroyKey(hKey);
684 ok(result, "%08lx\n", GetLastError());
687 if (!derive_key(CALG_RC4, &hKey, 56)) return;
689 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
690 ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
692 result = CryptDestroyKey(hKey);
693 ok(result, "%08lx\n", GetLastError());
696 static void test_import_private()
699 HCRYPTKEY hKeyExchangeKey, hSessionKey;
701 BYTE abPlainPrivateKey[596] = {
702 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
703 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
704 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
705 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
706 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
707 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
708 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
709 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
710 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
711 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
712 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
713 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
714 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
715 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
716 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
717 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
718 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
719 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
720 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
721 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
722 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
723 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
724 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
725 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
726 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
727 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
728 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
729 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
730 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
731 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
732 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
733 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
734 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
735 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
736 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
737 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
738 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
739 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
740 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
741 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
742 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
743 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
744 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
745 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
746 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
747 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
748 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
749 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
750 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
751 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
752 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
753 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
754 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
755 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
756 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
757 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
758 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
759 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
760 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
761 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
762 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
763 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
764 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
765 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
766 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
767 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
768 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
769 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
770 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
771 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
772 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
773 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
774 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
775 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
776 0xf2, 0x5d, 0x58, 0x07
778 BYTE abSessionKey[148] = {
779 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
780 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
781 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
782 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
783 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
784 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
785 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
786 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
787 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
788 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
789 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
790 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
791 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
792 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
793 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
794 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
795 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
796 0x04, 0x8c, 0x49, 0x92
798 BYTE abEncryptedMessage[12] = {
799 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
800 0x1c, 0xfd, 0xde, 0x71
803 dwLen = (DWORD)sizeof(abPlainPrivateKey);
804 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
806 /* rsaenh compiled without OpenSSL */
807 ok(GetLastError() == NTE_FAIL, "%08lx\n", GetLastError());
811 dwLen = (DWORD)sizeof(abSessionKey);
812 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
813 ok(result, "%08lx\n", GetLastError());
816 dwLen = (DWORD)sizeof(abEncryptedMessage);
817 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
818 ok(result && dwLen == 12 && !strcmp(abEncryptedMessage, "Wine rocks!"),
819 "%08lx, len: %ld\n", GetLastError(), dwLen);
821 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
823 dwLen = (DWORD)sizeof(abSessionKey);
824 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
825 ok(result, "%08lx\n", GetLastError());
828 dwLen = (DWORD)sizeof(abSessionKey);
829 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
830 ok(result, "%08lx\n", GetLastError());
834 static void test_verify_signature() {
836 HCRYPTKEY hPubSignKey;
837 BYTE abData[] = "Wine rocks!";
839 BYTE abPubKey[148] = {
840 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
841 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
842 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
843 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
844 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
845 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
846 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
847 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
848 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
849 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
850 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
851 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
852 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
853 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
854 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
855 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
856 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
857 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
858 0xe1, 0x21, 0x50, 0xac
860 /* md2 with hash oid */
861 BYTE abSignatureMD2[128] = {
862 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
863 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
864 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
865 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
866 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
867 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
868 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
869 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
870 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
871 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
872 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
873 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
874 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
875 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
876 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
877 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
879 /* md2 without hash oid */
880 BYTE abSignatureMD2NoOID[128] = {
881 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
882 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
883 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
884 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
885 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
886 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
887 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
888 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
889 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
890 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
891 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
892 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
893 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
894 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
895 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
896 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
898 /* md4 with hash oid */
899 BYTE abSignatureMD4[128] = {
900 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
901 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
902 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
903 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
904 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
905 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
906 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
907 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
908 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
909 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
910 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
911 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
912 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
913 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
914 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
915 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
917 /* md4 without hash oid */
918 BYTE abSignatureMD4NoOID[128] = {
919 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
920 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
921 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
922 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
923 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
924 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
925 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
926 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
927 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
928 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
929 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
930 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
931 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
932 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
933 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
934 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
936 /* md5 with hash oid */
937 BYTE abSignatureMD5[128] = {
938 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
939 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
940 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
941 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
942 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
943 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
944 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
945 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
946 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
947 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
948 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
949 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
950 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
951 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
952 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
953 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
955 /* md5 without hash oid */
956 BYTE abSignatureMD5NoOID[128] = {
957 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
958 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
959 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
960 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
961 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
962 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
963 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
964 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
965 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
966 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
967 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
968 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
969 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
970 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
971 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
972 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
974 /* sha with hash oid */
975 BYTE abSignatureSHA[128] = {
976 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
977 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
978 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
979 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
980 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
981 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
982 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
983 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
984 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
985 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
986 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
987 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
988 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
989 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
990 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
991 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
993 /* sha without hash oid */
994 BYTE abSignatureSHANoOID[128] = {
995 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
996 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
997 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
998 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
999 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1000 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1001 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1002 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1003 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1004 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1005 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1006 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1007 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1008 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1009 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1010 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1013 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1014 ok(result, "%08lx\n", GetLastError());
1015 if (!result) return;
1017 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1018 ok(result, "%08lx\n", GetLastError());
1019 if (!result) return;
1021 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1022 ok(result, "%08lx\n", GetLastError());
1023 if (!result) return;
1025 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1026 ok(result, "%08lx\n", GetLastError());
1027 if (!result) return;
1029 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1030 ok(result, "%08lx\n", GetLastError());
1031 if (!result) return;
1033 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1034 * the OID at all. */
1035 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1036 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1037 if (result) return;*/
1039 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1040 ok(result, "%08lx\n", GetLastError());
1041 if (!result) return;
1043 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1044 ok(result, "%08lx\n", GetLastError());
1045 if (!result) return;
1047 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1048 ok(result, "%08lx\n", GetLastError());
1049 if (!result) return;
1051 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1052 ok(result, "%08lx\n", GetLastError());
1053 if (!result) return;
1055 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1056 ok(result, "%08lx\n", GetLastError());
1057 if (!result) return;
1059 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1060 ok(result, "%08lx\n", GetLastError());
1061 if (!result) return;
1063 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1064 ok(result, "%08lx\n", GetLastError());
1065 if (!result) return;
1067 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1068 ok(result, "%08lx\n", GetLastError());
1069 if (!result) return;
1071 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1072 ok(result, "%08lx\n", GetLastError());
1073 if (!result) return;
1075 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1076 ok(result, "%08lx\n", GetLastError());
1077 if (!result) return;
1079 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1080 ok(result, "%08lx\n", GetLastError());
1081 if (!result) return;
1083 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1084 ok(result, "%08lx\n", GetLastError());
1085 if (!result) return;
1088 void test_rsa_encrypt()
1091 BYTE abData[2048] = "Wine rocks!";
1095 /* It is allowed to use the key exchange key for encryption/decryption */
1096 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1097 ok (result, "%08lx\n", GetLastError());
1098 if (!result) return;
1101 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1102 ok (result, "%08lx\n", GetLastError());
1103 if (!result) return;
1105 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1106 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08lx\n", GetLastError());
1108 CryptDestroyKey(hRSAKey);
1110 /* It is not allowed to use the signature key for encryption/decryption */
1111 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1112 ok (result, "%08lx\n", GetLastError());
1113 if (!result) return;
1116 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1117 ok (!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
1119 CryptDestroyKey(hRSAKey);
1122 void test_schannel_provider()
1125 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1126 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1129 SCHANNEL_ALG saSChannelAlg;
1130 CRYPT_DATA_BLOB data_blob;
1131 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1132 BYTE abPlainPrivateKey[596] = {
1133 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1134 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1135 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1136 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1137 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1138 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1139 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1140 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1141 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1142 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1143 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1144 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1145 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1146 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1147 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1148 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1149 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1150 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1151 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1152 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1153 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1154 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1155 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1156 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1157 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1158 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1159 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1160 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1161 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1162 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1163 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1164 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1165 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1166 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1167 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1168 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1169 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1170 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1171 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1172 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1173 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1174 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1175 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1176 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1177 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1178 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1179 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1180 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1181 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1182 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1183 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1184 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1185 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1186 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1187 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1188 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1189 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1190 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1191 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1192 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1193 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1194 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1195 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1196 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1197 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1198 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1199 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1200 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1201 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1202 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1203 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1204 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1205 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1206 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1207 0xf2, 0x5d, 0x58, 0x07
1209 BYTE abTLS1Master[140] = {
1210 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1211 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1212 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1213 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1214 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1215 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1216 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1217 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1218 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1219 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1220 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1221 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1222 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1223 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1224 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1225 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1226 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1227 0xd3, 0x1e, 0x82, 0xb3
1229 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1230 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1231 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1232 BYTE abClientFinished[16] = "client finished";
1233 BYTE abData[16] = "Wine rocks!";
1235 static const BYTE abEncryptedData[16] = {
1236 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1237 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1239 static const BYTE abPRF[16] = {
1240 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1241 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1243 static const BYTE abMD5[16] = {
1244 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1245 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1248 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1249 ok (result, "%08lx\n", GetLastError());
1250 if (!result) return;
1252 /* To get deterministic results, we import the TLS1 master secret (which
1253 * is typically generated from a random generator). Therefore, we need
1255 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1256 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1257 ok (result, "%08lx\n", GetLastError());
1258 if (!result) return;
1260 dwLen = (DWORD)sizeof(abTLS1Master);
1261 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1262 ok (result, "%08lx\n", GetLastError());
1263 if (!result) return;
1265 /* Setting the TLS1 client and server random parameters, as well as the
1266 * MAC and encryption algorithm parameters. */
1267 data_blob.cbData = 33;
1268 data_blob.pbData = abClientSecret;
1269 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1270 ok (result, "%08lx\n", GetLastError());
1271 if (!result) return;
1273 data_blob.cbData = 33;
1274 data_blob.pbData = abServerSecret;
1275 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1276 ok (result, "%08lx\n", GetLastError());
1277 if (!result) return;
1279 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1280 saSChannelAlg.Algid = CALG_DES;
1281 saSChannelAlg.cBits = 64;
1282 saSChannelAlg.dwFlags = 0;
1283 saSChannelAlg.dwReserved = 0;
1284 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1285 ok (result, "%08lx\n", GetLastError());
1286 if (!result) return;
1288 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1289 saSChannelAlg.Algid = CALG_MD5;
1290 saSChannelAlg.cBits = 128;
1291 saSChannelAlg.dwFlags = 0;
1292 saSChannelAlg.dwReserved = 0;
1293 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1294 ok (result, "%08lx\n", GetLastError());
1295 if (!result) return;
1297 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1298 * (Keys can only be derived from hashes, not from other keys.) */
1299 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1300 ok (result, "%08lx\n", GetLastError());
1301 if (!result) return;
1303 /* Deriving the server write encryption key from the master hash */
1304 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1305 ok (result, "%08lx\n", GetLastError());
1306 if (!result) return;
1308 /* Encrypting some data with the server write encryption key and checking the result. */
1310 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1311 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08lx\n", GetLastError());
1313 /* Second test case: Test the TLS1 pseudo random number function. */
1314 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1315 ok (result, "%08lx\n", GetLastError());
1316 if (!result) return;
1318 /* Set the label and seed parameters for the random number function */
1319 data_blob.cbData = 36;
1320 data_blob.pbData = abHashedHandshakes;
1321 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1322 ok (result, "%08lx\n", GetLastError());
1323 if (!result) return;
1325 data_blob.cbData = 15;
1326 data_blob.pbData = abClientFinished;
1327 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1328 ok (result, "%08lx\n", GetLastError());
1329 if (!result) return;
1331 /* Generate some pseudo random bytes and check if they are correct. */
1332 dwLen = (DWORD)sizeof(abData);
1333 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1334 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1335 "%08lx\n", GetLastError());
1337 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1338 * Hash some data with the HMAC. Compare results. */
1339 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1340 ok (result, "%08lx\n", GetLastError());
1341 if (!result) return;
1343 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1344 ok (result, "%08lx\n", GetLastError());
1345 if (!result) return;
1347 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1348 ok (result, "%08lx\n", GetLastError());
1349 if (!result) return;
1351 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1352 ok (result, "%08lx\n", GetLastError());
1353 if (!result) return;
1355 dwLen = (DWORD)sizeof(abMD5Hash);
1356 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1357 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08lx\n", GetLastError());
1359 CryptDestroyHash(hHMAC);
1360 CryptDestroyHash(hTLS1PRF);
1361 CryptDestroyHash(hMasterHash);
1362 CryptDestroyKey(hServerWriteMACKey);
1363 CryptDestroyKey(hServerWriteKey);
1364 CryptDestroyKey(hRSAKey);
1365 CryptDestroyKey(hMasterSecret);
1366 CryptReleaseContext(hProv, 0);
1369 void test_enum_container()
1371 BYTE abContainerName[256];
1373 BOOL result, fFound = FALSE;
1375 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1376 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1377 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1378 ok (result && dwBufferLen == MAX_PATH + 1, "%08lx\n", GetLastError());
1380 /* If the result fits into abContainerName dwBufferLen is left untouched */
1381 dwBufferLen = (DWORD)sizeof(abContainerName);
1382 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1383 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08lx\n", GetLastError());
1385 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1387 if (!strcmp(abContainerName, "winetest")) fFound = TRUE;
1388 dwBufferLen = (DWORD)sizeof(abContainerName);
1389 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1391 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08lx\n", fFound, GetLastError());
1396 if (!init_environment())
1408 test_block_cipher_modes();
1409 test_import_private();
1410 test_verify_signature();
1412 test_enum_container();
1413 clean_up_environment();
1414 test_schannel_provider();