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, %08lx\n", result, GetLastError());
66 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
68 ok(GetLastError()==NTE_BAD_KEYSET, "%08lx\n", GetLastError());
69 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
70 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
72 ok(result, "%08lx\n", GetLastError());
73 if (!result) return 0;
74 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
75 ok(result, "%08lx\n", GetLastError());
76 if (result) CryptDestroyKey(hKey);
77 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
78 ok(result, "%08lx\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, "%08lx\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, "%08lx, %ld\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, "%08lx, %ld\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, "%08lx\n", GetLastError());
124 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
125 ok(result, "%08lx\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, "%08lx\n", GetLastError());
145 ok(result, "%08lx\n", GetLastError());
146 if (!result) return FALSE;
147 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
148 ok(result, "%08lx\n", GetLastError());
149 if (!result) return FALSE;
150 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
151 ok(result, "%08lx\n", GetLastError());
152 if (!result) return FALSE;
154 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
155 ok(result, "%08lx\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, "%08lx\n", GetLastError());
189 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
190 ok(result, "%08lx\n", GetLastError());
193 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
194 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
197 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
198 ok(result, "%08lx\n", GetLastError());
200 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
202 result = CryptDestroyHash(hHash);
203 ok(result, "%08lx\n", GetLastError());
207 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
208 ok(result, "%08lx\n", GetLastError());
210 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
211 ok(result, "%08lx\n", GetLastError());
214 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
215 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
218 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
219 ok(result, "%08lx\n", GetLastError());
221 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
223 result = CryptDestroyHash(hHash);
224 ok(result, "%08lx\n", GetLastError());
227 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
228 ok(result, "%08lx\n", GetLastError());
230 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
231 ok(result, "%08lx\n", GetLastError());
234 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
235 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
238 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
239 ok(result, "%08lx\n", GetLastError());
241 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
243 result = CryptDestroyHash(hHash);
244 ok(result, "%08lx\n", GetLastError());
247 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
248 ok(result, "%08lx\n", GetLastError());
250 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
251 ok(result, "%08lx\n", GetLastError());
253 if(pCryptDuplicateHash) {
254 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
255 ok(result, "%08lx\n", GetLastError());
257 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
258 ok(result, "%08lx\n", GetLastError());
261 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
262 ok(result && (hashlen == 20), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
265 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
266 ok(result, "%08lx\n", GetLastError());
268 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
270 result = CryptDestroyHash(hHashClone);
271 ok(result, "%08lx\n", GetLastError());
274 result = CryptDestroyHash(hHash);
275 ok(result, "%08lx\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, "%08lx\n", GetLastError());
306 SetLastError(ERROR_SUCCESS);
308 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
309 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
310 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
312 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
313 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
314 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
316 dwMode = CRYPT_MODE_CBC;
317 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
318 ok(result, "%08lx\n", GetLastError());
321 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
322 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
323 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
325 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
326 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
327 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
329 dwMode = CRYPT_MODE_CFB;
330 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
331 ok(result, "%08lx\n", GetLastError());
334 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
335 ok(result && dwLen == 16, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
338 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
339 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
340 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
343 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
344 ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
347 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
348 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
349 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
351 dwMode = CRYPT_MODE_OFB;
352 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
353 ok(result, "%08lx\n", GetLastError());
356 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
357 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
360 static void test_3des112(void)
365 unsigned char pbData[16];
368 result = derive_key(CALG_3DES_112, &hKey, 0);
370 /* rsaenh compiled without OpenSSL */
371 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
375 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
378 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
379 ok(result, "%08lx\n", GetLastError());
381 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
382 ok(result, "%08lx\n", GetLastError());
384 result = CryptDestroyKey(hKey);
385 ok(result, "%08lx\n", GetLastError());
388 static void test_des(void)
393 unsigned char pbData[16];
396 result = derive_key(CALG_DES, &hKey, 56);
398 /* rsaenh compiled without OpenSSL */
399 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
403 dwMode = CRYPT_MODE_ECB;
404 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
405 ok(result, "%08lx\n", GetLastError());
407 dwLen = sizeof(DWORD);
408 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
409 ok(result, "%08lx\n", GetLastError());
411 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
414 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
415 ok(result, "%08lx\n", GetLastError());
417 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
418 ok(result, "%08lx\n", GetLastError());
420 result = CryptDestroyKey(hKey);
421 ok(result, "%08lx\n", GetLastError());
424 static void test_3des(void)
429 unsigned char pbData[16];
430 static const BYTE des3[16] = {
431 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
432 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
435 result = derive_key(CALG_3DES, &hKey, 0);
438 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
441 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
442 ok(result, "%08lx\n", GetLastError());
444 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
446 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
447 ok(result, "%08lx\n", GetLastError());
449 result = CryptDestroyKey(hKey);
450 ok(result, "%08lx\n", GetLastError());
453 static void test_rc2(void)
455 static const BYTE rc2encrypted[16] = {
456 0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
457 0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
461 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
463 unsigned char pbData[2000], pbHashValue[16];
466 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
469 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
471 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
473 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
474 ok(result, "%08lx\n", GetLastError());
477 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
478 ok(result, "%08lx\n", GetLastError());
480 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
481 ok(result, "%08lx\n", GetLastError());
483 dwLen = sizeof(DWORD);
484 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
485 ok(result, "%08lx\n", GetLastError());
487 dwMode = CRYPT_MODE_CBC;
488 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
489 ok(result, "%08lx\n", GetLastError());
491 dwLen = sizeof(DWORD);
492 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
493 ok(result, "%08lx\n", GetLastError());
495 dwLen = sizeof(DWORD);
496 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
497 ok(result, "%08lx\n", GetLastError());
499 dwLen = sizeof(DWORD);
500 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
501 ok(result, "%08lx\n", GetLastError());
503 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
504 ok(result, "%08lx\n", GetLastError());
505 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
506 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
507 HeapFree(GetProcessHeap(), 0, pbTemp);
509 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
510 ok(result, "%08lx\n", GetLastError());
511 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
512 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
513 HeapFree(GetProcessHeap(), 0, pbTemp);
515 dwLen = sizeof(DWORD);
516 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
518 result = CryptDestroyHash(hHash);
519 ok(result, "%08lx\n", GetLastError());
522 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
523 ok(result, "%08lx\n", GetLastError());
525 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
527 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
528 ok(result, "%08lx\n", GetLastError());
529 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
530 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
531 HeapFree(GetProcessHeap(), 0, pbTemp);
533 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
534 ok(result, "%08lx\n", GetLastError());
536 result = CryptDestroyKey(hKey);
537 ok(result, "%08lx\n", GetLastError());
541 static void test_rc4(void)
543 static const BYTE rc4[16] = {
544 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
545 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
549 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
550 unsigned char pbData[2000], *pbTemp;
551 unsigned char pszBuffer[256];
554 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
557 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
559 /* rsaenh compiled without OpenSSL */
560 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
562 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
563 ok(result, "%08lx\n", GetLastError());
566 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
567 ok(result, "%08lx\n", GetLastError());
569 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
570 ok(result, "%08lx\n", GetLastError());
572 dwLen = sizeof(DWORD);
573 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
574 ok(result, "%08lx\n", GetLastError());
576 dwLen = sizeof(DWORD);
577 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
578 ok(result, "%08lx\n", GetLastError());
580 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
581 ok(result, "%08lx\n", GetLastError());
582 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
583 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
584 HeapFree(GetProcessHeap(), 0, pbTemp);
586 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
587 ok(result, "%08lx\n", GetLastError());
588 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
589 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
590 HeapFree(GetProcessHeap(), 0, pbTemp);
592 dwLen = sizeof(DWORD);
593 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
595 result = CryptDestroyHash(hHash);
596 ok(result, "%08lx\n", GetLastError());
599 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
600 ok(result, "%08lx\n", GetLastError());
602 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
604 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
605 ok(result, "%08lx\n", GetLastError());
607 result = CryptDestroyKey(hKey);
608 ok(result, "%08lx\n", GetLastError());
612 static void test_hmac(void) {
616 HMAC_INFO hmacInfo = { CALG_MD2, NULL, 0, NULL, 0 };
619 static const BYTE hmac[16] = {
620 0xfd, 0x16, 0xb5, 0xb6, 0x13, 0x1c, 0x2b, 0xd6,
621 0x0a, 0xc7, 0xae, 0x92, 0x76, 0xa3, 0x05, 0x71 };
624 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
626 if (!derive_key(CALG_RC2, &hKey, 56)) return;
628 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
629 ok(result, "%08lx\n", GetLastError());
632 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
633 ok(result, "%08lx\n", GetLastError());
635 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
636 ok(result, "%08lx\n", GetLastError());
638 dwLen = sizeof(abData)/sizeof(BYTE);
639 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
640 ok(result, "%08lx\n", GetLastError());
642 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
644 result = CryptDestroyHash(hHash);
645 ok(result, "%08lx\n", GetLastError());
647 result = CryptDestroyKey(hKey);
648 ok(result, "%08lx\n", GetLastError());
651 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
652 ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
655 static void test_mac(void) {
660 BYTE abData[256], abEnc[264];
661 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
664 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
665 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
667 if (!derive_key(CALG_RC2, &hKey, 56)) return;
670 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
671 ok (result && dwLen == 264, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
673 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
674 ok(result, "%08lx\n", GetLastError());
677 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
678 ok(result, "%08lx\n", GetLastError());
680 dwLen = sizeof(abData)/sizeof(BYTE);
681 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
682 ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
684 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
686 result = CryptDestroyHash(hHash);
687 ok(result, "%08lx\n", GetLastError());
689 result = CryptDestroyKey(hKey);
690 ok(result, "%08lx\n", GetLastError());
693 if (!derive_key(CALG_RC4, &hKey, 56)) return;
695 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
696 ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
698 result = CryptDestroyKey(hKey);
699 ok(result, "%08lx\n", GetLastError());
702 static BYTE abPlainPrivateKey[596] = {
703 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
704 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
705 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
706 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
707 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
708 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
709 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
710 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
711 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
712 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
713 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
714 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
715 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
716 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
717 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
718 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
719 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
720 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
721 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
722 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
723 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
724 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
725 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
726 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
727 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
728 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
729 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
730 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
731 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
732 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
733 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
734 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
735 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
736 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
737 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
738 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
739 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
740 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
741 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
742 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
743 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
744 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
745 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
746 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
747 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
748 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
749 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
750 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
751 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
752 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
753 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
754 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
755 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
756 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
757 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
758 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
759 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
760 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
761 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
762 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
763 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
764 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
765 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
766 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
767 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
768 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
769 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
770 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
771 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
772 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
773 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
774 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
775 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
776 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
777 0xf2, 0x5d, 0x58, 0x07
780 static void test_import_private(void)
783 HCRYPTKEY hKeyExchangeKey, hSessionKey;
785 static BYTE abSessionKey[148] = {
786 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
787 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
788 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
789 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
790 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
791 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
792 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
793 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
794 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
795 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
796 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
797 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
798 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
799 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
800 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
801 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
802 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
803 0x04, 0x8c, 0x49, 0x92
805 static BYTE abEncryptedMessage[12] = {
806 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
807 0x1c, 0xfd, 0xde, 0x71
810 dwLen = (DWORD)sizeof(abPlainPrivateKey);
811 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
813 /* rsaenh compiled without OpenSSL */
814 ok(GetLastError() == NTE_FAIL, "%08lx\n", GetLastError());
818 dwLen = (DWORD)sizeof(abSessionKey);
819 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
820 ok(result, "%08lx\n", GetLastError());
823 dwLen = (DWORD)sizeof(abEncryptedMessage);
824 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
825 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
826 "%08lx, len: %ld\n", GetLastError(), dwLen);
828 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
830 dwLen = (DWORD)sizeof(abSessionKey);
831 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
832 ok(result, "%08lx\n", GetLastError());
835 dwLen = (DWORD)sizeof(abSessionKey);
836 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
837 ok(result, "%08lx\n", GetLastError());
841 static void test_verify_signature(void) {
843 HCRYPTKEY hPubSignKey;
844 BYTE abData[] = "Wine rocks!";
846 BYTE abPubKey[148] = {
847 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
848 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
849 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
850 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
851 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
852 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
853 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
854 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
855 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
856 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
857 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
858 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
859 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
860 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
861 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
862 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
863 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
864 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
865 0xe1, 0x21, 0x50, 0xac
867 /* md2 with hash oid */
868 BYTE abSignatureMD2[128] = {
869 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
870 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
871 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
872 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
873 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
874 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
875 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
876 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
877 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
878 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
879 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
880 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
881 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
882 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
883 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
884 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
886 /* md2 without hash oid */
887 BYTE abSignatureMD2NoOID[128] = {
888 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
889 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
890 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
891 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
892 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
893 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
894 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
895 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
896 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
897 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
898 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
899 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
900 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
901 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
902 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
903 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
905 /* md4 with hash oid */
906 BYTE abSignatureMD4[128] = {
907 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
908 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
909 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
910 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
911 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
912 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
913 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
914 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
915 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
916 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
917 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
918 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
919 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
920 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
921 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
922 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
924 /* md4 without hash oid */
925 BYTE abSignatureMD4NoOID[128] = {
926 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
927 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
928 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
929 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
930 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
931 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
932 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
933 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
934 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
935 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
936 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
937 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
938 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
939 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
940 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
941 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
943 /* md5 with hash oid */
944 BYTE abSignatureMD5[128] = {
945 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
946 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
947 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
948 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
949 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
950 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
951 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
952 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
953 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
954 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
955 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
956 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
957 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
958 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
959 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
960 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
962 /* md5 without hash oid */
963 BYTE abSignatureMD5NoOID[128] = {
964 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
965 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
966 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
967 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
968 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
969 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
970 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
971 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
972 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
973 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
974 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
975 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
976 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
977 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
978 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
979 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
981 /* sha with hash oid */
982 BYTE abSignatureSHA[128] = {
983 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
984 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
985 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
986 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
987 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
988 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
989 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
990 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
991 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
992 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
993 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
994 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
995 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
996 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
997 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
998 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1000 /* sha without hash oid */
1001 BYTE abSignatureSHANoOID[128] = {
1002 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1003 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1004 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1005 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1006 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1007 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1008 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1009 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1010 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1011 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1012 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1013 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1014 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1015 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1016 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1017 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1020 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1021 ok(result, "%08lx\n", GetLastError());
1022 if (!result) return;
1024 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1025 ok(result, "%08lx\n", GetLastError());
1026 if (!result) return;
1028 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1029 ok(result, "%08lx\n", GetLastError());
1030 if (!result) return;
1032 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1033 ok(result, "%08lx\n", GetLastError());
1034 if (!result) return;
1036 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1037 ok(result, "%08lx\n", GetLastError());
1038 if (!result) return;
1040 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1041 * the OID at all. */
1042 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1043 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1044 if (result) return;*/
1046 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1047 ok(result, "%08lx\n", GetLastError());
1048 if (!result) return;
1050 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1051 ok(result, "%08lx\n", GetLastError());
1052 if (!result) return;
1054 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1055 ok(result, "%08lx\n", GetLastError());
1056 if (!result) return;
1058 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1059 ok(result, "%08lx\n", GetLastError());
1060 if (!result) return;
1062 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1063 ok(result, "%08lx\n", GetLastError());
1064 if (!result) return;
1066 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1067 ok(result, "%08lx\n", GetLastError());
1068 if (!result) return;
1070 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1071 ok(result, "%08lx\n", GetLastError());
1072 if (!result) return;
1074 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1075 ok(result, "%08lx\n", GetLastError());
1076 if (!result) return;
1078 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1079 ok(result, "%08lx\n", GetLastError());
1080 if (!result) return;
1082 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1083 ok(result, "%08lx\n", GetLastError());
1084 if (!result) return;
1086 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1087 ok(result, "%08lx\n", GetLastError());
1088 if (!result) return;
1090 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1091 ok(result, "%08lx\n", GetLastError());
1092 if (!result) return;
1095 static void test_rsa_encrypt(void)
1098 BYTE abData[2048] = "Wine rocks!";
1102 /* It is allowed to use the key exchange key for encryption/decryption */
1103 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1104 ok (result, "%08lx\n", GetLastError());
1105 if (!result) return;
1108 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1109 ok (result, "%08lx\n", GetLastError());
1110 if (!result) return;
1112 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1113 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08lx\n", GetLastError());
1115 CryptDestroyKey(hRSAKey);
1117 /* It is not allowed to use the signature key for encryption/decryption */
1118 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1119 ok (result, "%08lx\n", GetLastError());
1120 if (!result) return;
1123 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1124 ok (!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
1126 CryptDestroyKey(hRSAKey);
1129 static void test_schannel_provider(void)
1132 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1133 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1136 SCHANNEL_ALG saSChannelAlg;
1137 CRYPT_DATA_BLOB data_blob;
1138 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1139 BYTE abPlainPrivateKey[596] = {
1140 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1141 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1142 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1143 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1144 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1145 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1146 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1147 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1148 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1149 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1150 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1151 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1152 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1153 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1154 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1155 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1156 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1157 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1158 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1159 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1160 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1161 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1162 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1163 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1164 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1165 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1166 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1167 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1168 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1169 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1170 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1171 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1172 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1173 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1174 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1175 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1176 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1177 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1178 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1179 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1180 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1181 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1182 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1183 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1184 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1185 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1186 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1187 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1188 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1189 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1190 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1191 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1192 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1193 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1194 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1195 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1196 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1197 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1198 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1199 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1200 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1201 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1202 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1203 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1204 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1205 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1206 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1207 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1208 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1209 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1210 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1211 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1212 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1213 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1214 0xf2, 0x5d, 0x58, 0x07
1216 BYTE abTLS1Master[140] = {
1217 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1218 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1219 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1220 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1221 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1222 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1223 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1224 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1225 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1226 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1227 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1228 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1229 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1230 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1231 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1232 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1233 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1234 0xd3, 0x1e, 0x82, 0xb3
1236 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1237 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1238 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1239 BYTE abClientFinished[16] = "client finished";
1240 BYTE abData[16] = "Wine rocks!";
1242 static const BYTE abEncryptedData[16] = {
1243 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1244 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1246 static const BYTE abPRF[16] = {
1247 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1248 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1250 static const BYTE abMD5[16] = {
1251 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1252 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1255 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1256 ok (result, "%08lx\n", GetLastError());
1257 if (!result) return;
1259 /* To get deterministic results, we import the TLS1 master secret (which
1260 * is typically generated from a random generator). Therefore, we need
1262 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1263 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1264 ok (result, "%08lx\n", GetLastError());
1265 if (!result) return;
1267 dwLen = (DWORD)sizeof(abTLS1Master);
1268 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1269 ok (result, "%08lx\n", GetLastError());
1270 if (!result) return;
1272 /* Setting the TLS1 client and server random parameters, as well as the
1273 * MAC and encryption algorithm parameters. */
1274 data_blob.cbData = 33;
1275 data_blob.pbData = abClientSecret;
1276 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1277 ok (result, "%08lx\n", GetLastError());
1278 if (!result) return;
1280 data_blob.cbData = 33;
1281 data_blob.pbData = abServerSecret;
1282 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1283 ok (result, "%08lx\n", GetLastError());
1284 if (!result) return;
1286 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1287 saSChannelAlg.Algid = CALG_DES;
1288 saSChannelAlg.cBits = 64;
1289 saSChannelAlg.dwFlags = 0;
1290 saSChannelAlg.dwReserved = 0;
1291 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1292 ok (result, "%08lx\n", GetLastError());
1293 if (!result) return;
1295 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1296 saSChannelAlg.Algid = CALG_MD5;
1297 saSChannelAlg.cBits = 128;
1298 saSChannelAlg.dwFlags = 0;
1299 saSChannelAlg.dwReserved = 0;
1300 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1301 ok (result, "%08lx\n", GetLastError());
1302 if (!result) return;
1304 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1305 * (Keys can only be derived from hashes, not from other keys.) */
1306 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1307 ok (result, "%08lx\n", GetLastError());
1308 if (!result) return;
1310 /* Deriving the server write encryption key from the master hash */
1311 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1312 ok (result, "%08lx\n", GetLastError());
1313 if (!result) return;
1315 /* Encrypting some data with the server write encryption key and checking the result. */
1317 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1318 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08lx\n", GetLastError());
1320 /* Second test case: Test the TLS1 pseudo random number function. */
1321 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1322 ok (result, "%08lx\n", GetLastError());
1323 if (!result) return;
1325 /* Set the label and seed parameters for the random number function */
1326 data_blob.cbData = 36;
1327 data_blob.pbData = abHashedHandshakes;
1328 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1329 ok (result, "%08lx\n", GetLastError());
1330 if (!result) return;
1332 data_blob.cbData = 15;
1333 data_blob.pbData = abClientFinished;
1334 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1335 ok (result, "%08lx\n", GetLastError());
1336 if (!result) return;
1338 /* Generate some pseudo random bytes and check if they are correct. */
1339 dwLen = (DWORD)sizeof(abData);
1340 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1341 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1342 "%08lx\n", GetLastError());
1344 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1345 * Hash some data with the HMAC. Compare results. */
1346 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1347 ok (result, "%08lx\n", GetLastError());
1348 if (!result) return;
1350 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1351 ok (result, "%08lx\n", GetLastError());
1352 if (!result) return;
1354 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1355 ok (result, "%08lx\n", GetLastError());
1356 if (!result) return;
1358 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1359 ok (result, "%08lx\n", GetLastError());
1360 if (!result) return;
1362 dwLen = (DWORD)sizeof(abMD5Hash);
1363 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1364 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08lx\n", GetLastError());
1366 CryptDestroyHash(hHMAC);
1367 CryptDestroyHash(hTLS1PRF);
1368 CryptDestroyHash(hMasterHash);
1369 CryptDestroyKey(hServerWriteMACKey);
1370 CryptDestroyKey(hServerWriteKey);
1371 CryptDestroyKey(hRSAKey);
1372 CryptDestroyKey(hMasterSecret);
1373 CryptReleaseContext(hProv, 0);
1374 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1377 static void test_enum_container(void)
1379 BYTE abContainerName[256];
1381 BOOL result, fFound = FALSE;
1383 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1384 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1385 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1386 ok (result && dwBufferLen == MAX_PATH + 1, "%08lx\n", GetLastError());
1388 /* If the result fits into abContainerName dwBufferLen is left untouched */
1389 dwBufferLen = (DWORD)sizeof(abContainerName);
1390 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1391 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08lx\n", GetLastError());
1393 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1395 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1396 dwBufferLen = (DWORD)sizeof(abContainerName);
1397 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1399 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08lx\n", fFound, GetLastError());
1402 static BYTE signBlob[] = {
1403 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1404 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1405 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1406 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1407 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1408 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1409 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1410 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1411 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1412 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1413 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1414 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1415 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1416 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1417 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1418 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1419 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1420 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1421 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1422 0xb6,0x85,0x86,0x07 };
1424 static void test_null_provider(void)
1429 DWORD keySpec, dataLen;
1431 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1432 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1433 "Expected NTE_BAD_PROV_TYPE, got %08lx\n", GetLastError());
1434 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1435 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1436 "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
1437 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1438 CRYPT_DELETEKEYSET);
1439 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1440 "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
1441 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1442 CRYPT_DELETEKEYSET);
1443 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1444 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
1445 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1446 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1447 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
1449 /* Delete the default container. */
1450 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1451 /* Once you've deleted the default container you can't open it as if it
1454 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1455 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1456 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
1457 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1458 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1459 CRYPT_VERIFYCONTEXT);
1460 ok(result, "CryptAcquireContext failed: %08lx\n", GetLastError());
1461 if (!result) return;
1462 dataLen = sizeof(keySpec);
1463 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1465 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1466 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08lx\n", keySpec);
1467 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1468 * supported, you can't get the keys from this container.
1470 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1471 ok(!result && GetLastError() == NTE_NO_KEY,
1472 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1473 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1474 ok(!result && GetLastError() == NTE_NO_KEY,
1475 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1476 result = CryptReleaseContext(prov, 0);
1477 ok(result, "CryptReleaseContext failed: %08lx\n", GetLastError());
1478 /* You can create a new default container. */
1479 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1481 ok(result, "CryptAcquireContext failed: %08lx\n", GetLastError());
1482 /* But you still can't get the keys (until one's been generated.) */
1483 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1484 ok(!result && GetLastError() == NTE_NO_KEY,
1485 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1486 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1487 ok(!result && GetLastError() == NTE_NO_KEY,
1488 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1489 CryptReleaseContext(prov, 0);
1490 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1492 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1493 CRYPT_DELETEKEYSET);
1494 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1495 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1496 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
1497 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1498 CRYPT_VERIFYCONTEXT);
1499 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1500 "Expected NTE_BAD_FLAGS, got %08lx\n", GetLastError());
1501 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1503 ok(result, "CryptAcquireContext failed: %08lx\n", GetLastError());
1504 if (!result) return;
1505 dataLen = sizeof(keySpec);
1506 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1508 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1509 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08lx\n", keySpec);
1510 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1511 ok(!result && GetLastError() == NTE_NO_KEY,
1512 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1513 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1514 ok(!result && GetLastError() == NTE_NO_KEY,
1515 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1517 /* Importing a key exchange blob.. */
1518 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1520 ok(result, "CryptImportKey failed: %08lx\n", GetLastError());
1521 CryptDestroyKey(key);
1522 /* allows access to the key exchange key.. */
1523 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1524 ok(result, "CryptGetUserKey failed: %08lx\n", GetLastError());
1525 CryptDestroyKey(key);
1526 /* but not to the private key. */
1527 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1528 ok(!result && GetLastError() == NTE_NO_KEY,
1529 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1530 CryptReleaseContext(prov, 0);
1531 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1532 CRYPT_DELETEKEYSET);
1534 /* Whereas importing a sign blob.. */
1535 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1537 ok(result, "CryptAcquireContext failed: %08lx\n", GetLastError());
1538 if (!result) return;
1539 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1540 ok(result, "CryptGenKey failed: %08lx\n", GetLastError());
1541 /* doesn't allow access to the key exchange key.. */
1542 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1543 ok(!result && GetLastError() == NTE_NO_KEY,
1544 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1545 /* but does to the private key. */
1546 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1547 ok(result, "CryptGetUserKey failed: %08lx\n", GetLastError());
1548 CryptDestroyKey(key);
1550 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1551 CRYPT_DELETEKEYSET);
1556 if (!init_environment())
1568 test_block_cipher_modes();
1569 test_import_private();
1570 test_verify_signature();
1572 test_enum_container();
1573 clean_up_environment();
1574 test_schannel_provider();
1575 test_null_provider();