rsaenh/tests: Remove duplicate abPlainPrivateKey variable.
[wine/testsucceed.git] / dlls / rsaenh / tests / rsaenh.c
blob6d4f5652cbb6356e1b7cd9fafab4f6d5de7e6f61
1 /*
2 * Unit tests for rsaenh functions
4 * Copyright (c) 2004 Michael Jung
5 * Copyright (c) 2006 Juan Lang
6 * Copyright (c) 2007 Vijay Kiran Kamuju
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <string.h>
24 #include <stdio.h>
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wincrypt.h"
31 static HCRYPTPROV hProv;
32 static const char szContainer[] = "winetest";
33 static const unsigned char pbData[] = "Wine rocks totally!";
34 static const char szProvider[] = MS_ENHANCED_PROV_A;
36 typedef struct _ctdatatype {
37 unsigned char origstr[32];
38 unsigned char decstr[32];
39 int strlen;
40 int enclen;
41 int buflen;
42 } cryptdata;
44 static const cryptdata cTestData[4] = {
45 {"abcdefghijkl",
46 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
47 12,8,16},
48 {"abcdefghij",
49 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
50 10,8,16},
51 {"abcdefgh",
52 {'a','b','c','d','e','f','g','h',0},
53 8,8,16},
54 {"abcdefghijkl",
55 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
56 12,12,16}
59 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
61 size_t i;
62 printf("%s: ",heading);
63 for(i=0;i<cb;i++)
64 printf("0x%02x,",pb[i]);
65 putchar('\n');
68 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
71 static void trace_hex(BYTE *pbData, DWORD dwLen) {
72 char szTemp[256];
73 DWORD i, j;
75 for (i = 0; i < dwLen-7; i+=8) {
76 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
77 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
78 pbData[i+6], pbData[i+7]);
79 trace(szTemp);
81 for (j=0; i<dwLen; j++,i++) {
82 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
84 trace(szTemp);
88 static int init_base_environment(void)
90 HCRYPTKEY hKey;
91 BOOL result;
93 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
95 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
97 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
98 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
100 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
102 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
103 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
104 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
105 CRYPT_NEWKEYSET);
106 ok(result, "%08x\n", GetLastError());
107 if (!result) return 0;
108 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
109 ok(result, "%08x\n", GetLastError());
110 if (result) CryptDestroyKey(hKey);
111 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
112 ok(result, "%08x\n", GetLastError());
113 if (result) CryptDestroyKey(hKey);
115 return 1;
118 static void clean_up_base_environment(void)
120 BOOL result;
122 result = CryptReleaseContext(hProv, 1);
123 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
125 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
128 static int init_aes_environment(void)
130 HCRYPTKEY hKey;
131 BOOL result;
133 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
135 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
137 /* we are using NULL as provider name for RSA_AES provider as the provider
138 * names are different in Windows XP and Vista. Its different as to what
139 * its defined in the SDK on Windows XP.
140 * This provider is available on Windows XP, Windows 2003 and Vista. */
142 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
143 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
145 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
147 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
148 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
149 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
150 CRYPT_NEWKEYSET);
151 ok(result, "%08x\n", GetLastError());
152 if (!result) return 0;
153 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
154 ok(result, "%08x\n", GetLastError());
155 if (result) CryptDestroyKey(hKey);
156 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
157 ok(result, "%08x\n", GetLastError());
158 if (result) CryptDestroyKey(hKey);
160 return 1;
163 static void clean_up_aes_environment(void)
165 BOOL result;
167 result = CryptReleaseContext(hProv, 1);
168 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
170 CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
173 static void test_prov(void)
175 BOOL result;
176 DWORD dwLen, dwInc;
178 dwLen = (DWORD)sizeof(DWORD);
179 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
180 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
182 dwLen = (DWORD)sizeof(DWORD);
183 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
184 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
187 static void test_gen_random(void)
189 BOOL result;
190 BYTE rnd1[16], rnd2[16];
192 memset(rnd1, 0, sizeof(rnd1));
193 memset(rnd2, 0, sizeof(rnd2));
195 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
196 if (!result && GetLastError() == NTE_FAIL) {
197 /* rsaenh compiled without OpenSSL */
198 return;
201 ok(result, "%08x\n", GetLastError());
203 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
204 ok(result, "%08x\n", GetLastError());
206 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
209 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
211 HCRYPTHASH hHash;
212 BOOL result;
213 unsigned char pbData[2000];
214 int i;
216 *phKey = (HCRYPTKEY)NULL;
217 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
218 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
219 if (!result) {
220 /* rsaenh compiled without OpenSSL */
221 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
222 return FALSE;
224 ok(result, "%08x\n", GetLastError());
225 if (!result) return FALSE;
226 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
227 ok(result, "%08x\n", GetLastError());
228 if (!result) return FALSE;
229 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
230 ok(result, "%08x\n", GetLastError());
231 if (!result) return FALSE;
232 len = 2000;
233 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
234 ok(result, "%08x\n", GetLastError());
235 CryptDestroyHash(hHash);
236 return TRUE;
239 static void test_hashes(void)
241 static const unsigned char md2hash[16] = {
242 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
243 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
244 static const unsigned char md4hash[16] = {
245 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
246 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
247 static const unsigned char empty_md5hash[16] = {
248 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
249 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
250 static const unsigned char md5hash[16] = {
251 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
252 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
253 static const unsigned char sha1hash[20] = {
254 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
255 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
256 unsigned char pbData[2048];
257 BOOL result;
258 HCRYPTHASH hHash, hHashClone;
259 BYTE pbHashValue[36];
260 DWORD hashlen, len;
261 int i;
263 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
265 /* MD2 Hashing */
266 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
267 if (!result) {
268 /* rsaenh compiled without OpenSSL */
269 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
270 } else {
271 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
272 ok(result, "%08x\n", GetLastError());
274 len = sizeof(DWORD);
275 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
276 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
278 len = 16;
279 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
280 ok(result, "%08x\n", GetLastError());
282 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
284 result = CryptDestroyHash(hHash);
285 ok(result, "%08x\n", GetLastError());
288 /* MD4 Hashing */
289 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
290 ok(result, "%08x\n", GetLastError());
292 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
293 ok(result, "%08x\n", GetLastError());
295 len = sizeof(DWORD);
296 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
297 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
299 len = 16;
300 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
301 ok(result, "%08x\n", GetLastError());
303 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
305 result = CryptDestroyHash(hHash);
306 ok(result, "%08x\n", GetLastError());
308 /* MD5 Hashing */
309 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
310 ok(result, "%08x\n", GetLastError());
312 len = sizeof(DWORD);
313 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
314 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
316 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
317 ok(result, "%08x\n", GetLastError());
319 len = 16;
320 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
321 ok(result, "%08x\n", GetLastError());
323 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
325 result = CryptDestroyHash(hHash);
326 ok(result, "%08x\n", GetLastError());
328 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
329 ok(result, "%08x\n", GetLastError());
331 /* The hash is available even if CryptHashData hasn't been called */
332 len = 16;
333 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
334 ok(result, "%08x\n", GetLastError());
336 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
338 /* It's also stable: getting it twice results in the same value */
339 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
340 ok(result, "%08x\n", GetLastError());
342 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
344 /* Can't add data after the hash been retrieved */
345 SetLastError(0xdeadbeef);
346 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
347 ok(!result && GetLastError() == NTE_BAD_HASH_STATE, "%08x\n", GetLastError());
349 /* You can still retrieve the hash, its value just hasn't changed */
350 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
351 ok(result, "%08x\n", GetLastError());
353 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
355 result = CryptDestroyHash(hHash);
356 ok(result, "%08x\n", GetLastError());
358 /* SHA1 Hashing */
359 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
360 ok(result, "%08x\n", GetLastError());
362 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
363 ok(result, "%08x\n", GetLastError());
365 if(pCryptDuplicateHash) {
366 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
367 ok(result, "%08x\n", GetLastError());
369 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
370 ok(result, "%08x\n", GetLastError());
372 len = sizeof(DWORD);
373 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
374 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
376 len = 20;
377 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
378 ok(result, "%08x\n", GetLastError());
380 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
382 result = CryptDestroyHash(hHashClone);
383 ok(result, "%08x\n", GetLastError());
386 result = CryptDestroyHash(hHash);
387 ok(result, "%08x\n", GetLastError());
390 static void test_block_cipher_modes(void)
392 static const BYTE plain[23] = {
393 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
394 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
395 static const BYTE ecb[24] = {
396 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
397 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
398 static const BYTE cbc[24] = {
399 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
400 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
401 static const BYTE cfb[24] = {
402 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
403 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
404 HCRYPTKEY hKey;
405 BOOL result;
406 BYTE abData[24];
407 DWORD dwMode, dwLen;
409 result = derive_key(CALG_RC2, &hKey, 40);
410 if (!result) return;
412 memcpy(abData, plain, sizeof(abData));
414 dwMode = CRYPT_MODE_ECB;
415 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
416 ok(result, "%08x\n", GetLastError());
418 dwLen = 23;
419 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
420 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
421 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
423 SetLastError(ERROR_SUCCESS);
424 dwLen = 23;
425 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
426 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
427 "%08x, dwLen: %d\n", GetLastError(), dwLen);
429 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
430 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
431 "%08x, dwLen: %d\n", GetLastError(), dwLen);
433 dwMode = CRYPT_MODE_CBC;
434 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
435 ok(result, "%08x\n", GetLastError());
437 dwLen = 23;
438 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
439 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
440 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
442 dwLen = 23;
443 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
444 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
445 "%08x, dwLen: %d\n", GetLastError(), dwLen);
447 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
448 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
449 "%08x, dwLen: %d\n", GetLastError(), dwLen);
451 dwMode = CRYPT_MODE_CFB;
452 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
453 ok(result, "%08x\n", GetLastError());
455 dwLen = 16;
456 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
457 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
459 dwLen = 7;
460 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
461 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
462 "%08x, dwLen: %d\n", GetLastError(), dwLen);
464 dwLen = 8;
465 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
466 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
468 dwLen = 16;
469 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
470 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
471 "%08x, dwLen: %d\n", GetLastError(), dwLen);
473 dwMode = CRYPT_MODE_OFB;
474 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
475 ok(result, "%08x\n", GetLastError());
477 dwLen = 23;
478 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
479 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
481 CryptDestroyKey(hKey);
484 static void test_3des112(void)
486 HCRYPTKEY hKey;
487 BOOL result;
488 DWORD dwLen;
489 unsigned char pbData[16];
490 int i;
492 result = derive_key(CALG_3DES_112, &hKey, 0);
493 if (!result) {
494 /* rsaenh compiled without OpenSSL */
495 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
496 return;
499 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
501 dwLen = 13;
502 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
503 ok(result, "%08x\n", GetLastError());
505 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
506 ok(result, "%08x\n", GetLastError());
508 for (i=0; i<4; i++)
510 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
512 dwLen = cTestData[i].enclen;
513 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
514 ok(result, "%08x\n", GetLastError());
515 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
517 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
518 ok(result, "%08x\n", GetLastError());
519 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
520 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
521 if((dwLen != cTestData[i].enclen) ||
522 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
524 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
525 printBytes("got",pbData,dwLen);
528 result = CryptDestroyKey(hKey);
529 ok(result, "%08x\n", GetLastError());
532 static void test_des(void)
534 HCRYPTKEY hKey;
535 BOOL result;
536 DWORD dwLen, dwMode;
537 unsigned char pbData[16];
538 int i;
540 result = derive_key(CALG_DES, &hKey, 56);
541 if (!result) {
542 /* rsaenh compiled without OpenSSL */
543 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
544 return;
547 dwMode = CRYPT_MODE_ECB;
548 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
549 ok(result, "%08x\n", GetLastError());
551 dwLen = sizeof(DWORD);
552 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
553 ok(result, "%08x\n", GetLastError());
555 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
557 dwLen = 13;
558 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
559 ok(result, "%08x\n", GetLastError());
561 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
562 ok(result, "%08x\n", GetLastError());
564 for (i=0; i<4; i++)
566 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
568 dwLen = cTestData[i].enclen;
569 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
570 ok(result, "%08x\n", GetLastError());
571 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
573 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
574 ok(result, "%08x\n", GetLastError());
575 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
576 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
577 if((dwLen != cTestData[i].enclen) ||
578 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
580 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
581 printBytes("got",pbData,dwLen);
585 result = CryptDestroyKey(hKey);
586 ok(result, "%08x\n", GetLastError());
589 static void test_3des(void)
591 HCRYPTKEY hKey;
592 BOOL result;
593 DWORD dwLen;
594 unsigned char pbData[16];
595 static const BYTE des3[16] = {
596 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
597 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
598 int i;
600 result = derive_key(CALG_3DES, &hKey, 0);
601 if (!result) return;
603 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
605 dwLen = 13;
606 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
607 ok(result, "%08x\n", GetLastError());
609 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
611 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
612 ok(result, "%08x\n", GetLastError());
614 for (i=0; i<4; i++)
616 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
618 dwLen = cTestData[i].enclen;
619 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
620 ok(result, "%08x\n", GetLastError());
621 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
623 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
624 ok(result, "%08x\n", GetLastError());
625 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
626 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
627 if((dwLen != cTestData[i].enclen) ||
628 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
630 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
631 printBytes("got",pbData,dwLen);
634 result = CryptDestroyKey(hKey);
635 ok(result, "%08x\n", GetLastError());
638 static void test_aes(int keylen)
640 HCRYPTKEY hKey;
641 BOOL result;
642 DWORD dwLen;
643 unsigned char pbData[16];
644 int i;
646 switch (keylen)
648 case 256:
649 result = derive_key(CALG_AES_256, &hKey, 0);
650 break;
651 case 192:
652 result = derive_key(CALG_AES_192, &hKey, 0);
653 break;
654 default:
655 case 128:
656 result = derive_key(CALG_AES_128, &hKey, 0);
657 break;
659 if (!result) return;
661 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
663 dwLen = 13;
664 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
665 ok(result, "%08x\n", GetLastError());
667 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
668 ok(result, "%08x\n", GetLastError());
670 for (i=0; i<4; i++)
672 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
674 dwLen = cTestData[i].enclen;
675 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
676 ok(result, "%08x\n", GetLastError());
677 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
679 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
680 ok(result, "%08x\n", GetLastError());
681 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
682 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
683 if((dwLen != cTestData[i].enclen) ||
684 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
686 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
687 printBytes("got",pbData,dwLen);
690 result = CryptDestroyKey(hKey);
691 ok(result, "%08x\n", GetLastError());
694 static void test_rc2(void)
696 static const BYTE rc2encrypted[16] = {
697 0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
698 0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
699 static const BYTE rc2_128_encrypted[] = {
700 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
701 0xb6,0x66 };
702 HCRYPTHASH hHash;
703 HCRYPTKEY hKey;
704 BOOL result;
705 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
706 BYTE *pbTemp;
707 unsigned char pbData[2000], pbHashValue[16];
708 int i;
710 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
712 /* MD2 Hashing */
713 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
714 if (!result) {
715 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
716 } else {
717 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
718 ok(result, "%08x\n", GetLastError());
720 dwLen = 16;
721 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
722 ok(result, "%08x\n", GetLastError());
724 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
725 ok(result, "%08x\n", GetLastError());
727 dwLen = sizeof(DWORD);
728 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
729 ok(result, "%08x\n", GetLastError());
731 dwMode = CRYPT_MODE_CBC;
732 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
733 ok(result, "%08x\n", GetLastError());
735 dwLen = sizeof(DWORD);
736 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
737 ok(result, "%08x\n", GetLastError());
739 dwLen = sizeof(DWORD);
740 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
741 ok(result, "%08x\n", GetLastError());
743 dwLen = sizeof(DWORD);
744 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
745 ok(result, "%08x\n", GetLastError());
747 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
748 ok(result, "%08x\n", GetLastError());
749 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
750 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
751 HeapFree(GetProcessHeap(), 0, pbTemp);
753 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
754 ok(result, "%08x\n", GetLastError());
755 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
756 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
757 HeapFree(GetProcessHeap(), 0, pbTemp);
759 dwLen = sizeof(DWORD);
760 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
762 result = CryptDestroyHash(hHash);
763 ok(result, "%08x\n", GetLastError());
765 dwDataLen = 13;
766 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
767 ok(result, "%08x\n", GetLastError());
769 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
771 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
772 ok(result, "%08x\n", GetLastError());
773 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
774 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
775 HeapFree(GetProcessHeap(), 0, pbTemp);
777 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
778 ok(result, "%08x\n", GetLastError());
780 result = CryptDestroyKey(hKey);
781 ok(result, "%08x\n", GetLastError());
784 /* Again, but test setting the effective key len */
785 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
787 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
788 if (!result) {
789 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
790 } else {
791 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
792 ok(result, "%08x\n", GetLastError());
794 dwLen = 16;
795 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
796 ok(result, "%08x\n", GetLastError());
798 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
799 ok(result, "%08x\n", GetLastError());
801 SetLastError(0xdeadbeef);
802 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
803 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
804 dwKeyLen = 0;
805 SetLastError(0xdeadbeef);
806 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
807 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
808 dwKeyLen = 1025;
809 SetLastError(0xdeadbeef);
810 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
812 dwLen = sizeof(dwKeyLen);
813 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
814 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
815 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
816 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
818 dwKeyLen = 128;
819 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
820 ok(result, "%d\n", GetLastError());
822 dwLen = sizeof(dwKeyLen);
823 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
824 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
825 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
826 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
828 result = CryptDestroyHash(hHash);
829 ok(result, "%08x\n", GetLastError());
831 dwDataLen = 13;
832 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
833 ok(result, "%08x\n", GetLastError());
835 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
836 "RC2 encryption failed!\n");
838 /* Oddly enough this succeeds, though it should have no effect */
839 dwKeyLen = 40;
840 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
841 ok(result, "%d\n", GetLastError());
843 result = CryptDestroyKey(hKey);
844 ok(result, "%08x\n", GetLastError());
848 static void test_rc4(void)
850 static const BYTE rc4[16] = {
851 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
852 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
853 BOOL result;
854 HCRYPTHASH hHash;
855 HCRYPTKEY hKey;
856 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
857 unsigned char pbData[2000], *pbTemp;
858 unsigned char pszBuffer[256];
859 int i;
861 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
863 /* MD2 Hashing */
864 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
865 if (!result) {
866 /* rsaenh compiled without OpenSSL */
867 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
868 } else {
869 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
870 ok(result, "%08x\n", GetLastError());
872 dwLen = 16;
873 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
874 ok(result, "%08x\n", GetLastError());
876 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
877 ok(result, "%08x\n", GetLastError());
879 dwLen = sizeof(DWORD);
880 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
881 ok(result, "%08x\n", GetLastError());
883 dwLen = sizeof(DWORD);
884 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
885 ok(result, "%08x\n", GetLastError());
887 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
888 ok(result, "%08x\n", GetLastError());
889 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
890 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
891 HeapFree(GetProcessHeap(), 0, pbTemp);
893 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
894 ok(result, "%08x\n", GetLastError());
895 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
896 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
897 HeapFree(GetProcessHeap(), 0, pbTemp);
899 dwLen = sizeof(DWORD);
900 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
902 result = CryptDestroyHash(hHash);
903 ok(result, "%08x\n", GetLastError());
905 dwDataLen = 16;
906 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
907 ok(result, "%08x\n", GetLastError());
908 dwDataLen = 16;
909 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
910 ok(result, "%08x\n", GetLastError());
912 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
914 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
915 ok(result, "%08x\n", GetLastError());
917 result = CryptDestroyKey(hKey);
918 ok(result, "%08x\n", GetLastError());
922 static void test_hmac(void) {
923 HCRYPTKEY hKey;
924 HCRYPTHASH hHash;
925 BOOL result;
926 /* Using CALG_MD2 here fails on Windows 2003, why ? */
927 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
928 DWORD dwLen;
929 BYTE abData[256];
930 static const BYTE hmac[16] = {
931 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
932 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
933 int i;
935 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
937 if (!derive_key(CALG_RC2, &hKey, 56)) return;
939 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
940 ok(result, "%08x\n", GetLastError());
941 if (!result) return;
943 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
944 ok(result, "%08x\n", GetLastError());
946 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
947 ok(result, "%08x\n", GetLastError());
949 dwLen = sizeof(abData)/sizeof(BYTE);
950 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
951 ok(result, "%08x\n", GetLastError());
953 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
955 result = CryptDestroyHash(hHash);
956 ok(result, "%08x\n", GetLastError());
958 result = CryptDestroyKey(hKey);
959 ok(result, "%08x\n", GetLastError());
961 /* Provoke errors */
962 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
963 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
966 static void test_mac(void) {
967 HCRYPTKEY hKey;
968 HCRYPTHASH hHash;
969 BOOL result;
970 DWORD dwLen;
971 BYTE abData[256], abEnc[264];
972 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
973 int i;
975 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
976 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
978 if (!derive_key(CALG_RC2, &hKey, 56)) return;
980 dwLen = 256;
981 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
982 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
984 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
985 ok(result, "%08x\n", GetLastError());
986 if (!result) return;
988 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
989 ok(result, "%08x\n", GetLastError());
991 dwLen = sizeof(abData)/sizeof(BYTE);
992 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
993 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
995 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
997 result = CryptDestroyHash(hHash);
998 ok(result, "%08x\n", GetLastError());
1000 result = CryptDestroyKey(hKey);
1001 ok(result, "%08x\n", GetLastError());
1003 /* Provoke errors */
1004 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1006 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1007 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1009 result = CryptDestroyKey(hKey);
1010 ok(result, "%08x\n", GetLastError());
1013 static BYTE abPlainPrivateKey[596] = {
1014 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1015 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1016 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1017 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1018 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1019 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1020 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1021 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1022 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1023 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1024 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1025 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1026 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1027 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1028 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1029 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1030 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1031 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1032 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1033 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1034 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1035 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1036 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1037 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1038 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1039 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1040 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1041 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1042 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1043 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1044 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1045 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1046 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1047 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1048 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1049 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1050 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1051 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1052 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1053 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1054 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1055 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1056 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1057 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1058 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1059 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1060 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1061 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1062 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1063 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1064 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1065 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1066 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1067 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1068 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1069 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1070 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1071 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1072 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1073 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1074 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1075 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1076 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1077 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1078 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1079 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1080 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1081 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1082 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1083 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1084 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1085 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1086 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1087 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1088 0xf2, 0x5d, 0x58, 0x07
1091 static void test_import_private(void)
1093 DWORD dwLen;
1094 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1095 BOOL result;
1096 static BYTE abSessionKey[148] = {
1097 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1098 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1099 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1100 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1101 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1102 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1103 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1104 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1105 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1106 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1107 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1108 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1109 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1110 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1111 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1112 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1113 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1114 0x04, 0x8c, 0x49, 0x92
1116 static BYTE abEncryptedMessage[12] = {
1117 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1118 0x1c, 0xfd, 0xde, 0x71
1121 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1122 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1123 if (!result) {
1124 /* rsaenh compiled without OpenSSL */
1125 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1126 return;
1129 dwLen = (DWORD)sizeof(abSessionKey);
1130 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1131 ok(result, "%08x\n", GetLastError());
1132 if (!result) return;
1134 dwLen = (DWORD)sizeof(abEncryptedMessage);
1135 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1136 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1137 "%08x, len: %d\n", GetLastError(), dwLen);
1138 CryptDestroyKey(hSessionKey);
1140 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1142 dwLen = (DWORD)sizeof(abSessionKey);
1143 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1144 ok(result, "%08x\n", GetLastError());
1145 CryptDestroyKey(hSessionKey);
1146 if (!result) return;
1148 dwLen = (DWORD)sizeof(abSessionKey);
1149 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1150 ok(result, "%08x\n", GetLastError());
1151 if (!result) return;
1153 CryptDestroyKey(hSessionKey);
1154 CryptDestroyKey(hKeyExchangeKey);
1157 static void test_verify_signature(void) {
1158 HCRYPTHASH hHash;
1159 HCRYPTKEY hPubSignKey;
1160 BYTE abData[] = "Wine rocks!";
1161 BOOL result;
1162 BYTE abPubKey[148] = {
1163 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1164 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1165 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1166 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1167 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1168 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1169 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1170 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1171 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1172 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1173 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1174 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1175 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1176 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1177 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1178 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1179 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1180 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1181 0xe1, 0x21, 0x50, 0xac
1183 /* md2 with hash oid */
1184 BYTE abSignatureMD2[128] = {
1185 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1186 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1187 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1188 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1189 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1190 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1191 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1192 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1193 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1194 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1195 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1196 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1197 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1198 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1199 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1200 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1202 /* md2 without hash oid */
1203 BYTE abSignatureMD2NoOID[128] = {
1204 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1205 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1206 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1207 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1208 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1209 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1210 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1211 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1212 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1213 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1214 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1215 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1216 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1217 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1218 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1219 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1221 /* md4 with hash oid */
1222 BYTE abSignatureMD4[128] = {
1223 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1224 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1225 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1226 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1227 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1228 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1229 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1230 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1231 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1232 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1233 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1234 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1235 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1236 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1237 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1238 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1240 /* md4 without hash oid */
1241 BYTE abSignatureMD4NoOID[128] = {
1242 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1243 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1244 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1245 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1246 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1247 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1248 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1249 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1250 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1251 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1252 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1253 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1254 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1255 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1256 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1257 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1259 /* md5 with hash oid */
1260 BYTE abSignatureMD5[128] = {
1261 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1262 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1263 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1264 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1265 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1266 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1267 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1268 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1269 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1270 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1271 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1272 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1273 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1274 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1275 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1276 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1278 /* md5 without hash oid */
1279 BYTE abSignatureMD5NoOID[128] = {
1280 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1281 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1282 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1283 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1284 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1285 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1286 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1287 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1288 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1289 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1290 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1291 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1292 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1293 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1294 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1295 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1297 /* sha with hash oid */
1298 BYTE abSignatureSHA[128] = {
1299 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1300 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1301 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1302 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1303 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1304 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1305 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1306 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1307 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1308 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1309 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1310 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1311 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1312 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1313 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1314 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1316 /* sha without hash oid */
1317 BYTE abSignatureSHANoOID[128] = {
1318 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1319 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1320 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1321 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1322 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1323 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1324 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1325 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1326 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1327 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1328 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1329 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1330 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1331 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1332 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1333 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1336 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1337 ok(result, "%08x\n", GetLastError());
1338 if (!result) return;
1340 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1341 ok(result, "%08x\n", GetLastError());
1342 if (!result) return;
1344 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1345 ok(result, "%08x\n", GetLastError());
1346 if (!result) return;
1348 /*check that a NULL pointer signature is correctly handled*/
1349 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1350 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1351 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1352 if (result) return;
1354 /* check that we get a bad signature error when the signature is too short*/
1355 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1356 ok(!result && NTE_BAD_SIGNATURE == GetLastError(),
1357 "Expected NTE_BAD_SIGNATURE error, got %08x\n", GetLastError());
1358 if (result) return;
1360 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1361 ok(result, "%08x\n", GetLastError());
1362 if (!result) return;
1364 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1365 ok(result, "%08x\n", GetLastError());
1366 if (!result) return;
1368 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1369 * the OID at all. */
1370 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1371 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1372 if (result) return;*/
1374 CryptDestroyHash(hHash);
1376 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1377 ok(result, "%08x\n", GetLastError());
1378 if (!result) return;
1380 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1381 ok(result, "%08x\n", GetLastError());
1382 if (!result) return;
1384 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1385 ok(result, "%08x\n", GetLastError());
1386 if (!result) return;
1388 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1389 ok(result, "%08x\n", GetLastError());
1390 if (!result) return;
1392 CryptDestroyHash(hHash);
1394 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1395 ok(result, "%08x\n", GetLastError());
1396 if (!result) return;
1398 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1399 ok(result, "%08x\n", GetLastError());
1400 if (!result) return;
1402 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1403 ok(result, "%08x\n", GetLastError());
1404 if (!result) return;
1406 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1407 ok(result, "%08x\n", GetLastError());
1408 if (!result) return;
1410 CryptDestroyHash(hHash);
1412 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1413 ok(result, "%08x\n", GetLastError());
1414 if (!result) return;
1416 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1417 ok(result, "%08x\n", GetLastError());
1418 if (!result) return;
1420 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1421 ok(result, "%08x\n", GetLastError());
1422 if (!result) return;
1424 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1425 ok(result, "%08x\n", GetLastError());
1426 if (!result) return;
1428 CryptDestroyHash(hHash);
1429 CryptDestroyKey(hPubSignKey);
1432 static void test_rsa_encrypt(void)
1434 HCRYPTKEY hRSAKey;
1435 BYTE abData[2048] = "Wine rocks!";
1436 BOOL result;
1437 DWORD dwLen;
1439 /* It is allowed to use the key exchange key for encryption/decryption */
1440 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1441 ok (result, "%08x\n", GetLastError());
1442 if (!result) return;
1444 dwLen = 12;
1445 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1446 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1447 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1448 dwLen = 12;
1449 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1450 ok (result, "%08x\n", GetLastError());
1451 if (!result) return;
1453 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1454 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1456 CryptDestroyKey(hRSAKey);
1458 /* It is not allowed to use the signature key for encryption/decryption */
1459 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1460 ok (result, "%08x\n", GetLastError());
1461 if (!result) return;
1463 dwLen = 12;
1464 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1465 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1467 CryptDestroyKey(hRSAKey);
1470 static void test_import_export(void)
1472 DWORD dwLen, dwDataLen;
1473 HCRYPTKEY hPublicKey;
1474 BOOL result;
1475 ALG_ID algID;
1476 BYTE emptyKey[2048];
1477 static BYTE abPlainPublicKey[84] = {
1478 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1479 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1480 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1481 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1482 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1483 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1484 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1485 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1486 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1487 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1488 0x11, 0x11, 0x11, 0x11
1491 dwLen=84;
1492 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1493 ok(result, "failed to import the public key\n");
1495 dwDataLen=sizeof(algID);
1496 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1497 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1498 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1500 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1501 ok(result, "failed to export the fresh imported public key\n");
1502 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1503 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1505 CryptDestroyKey(hPublicKey);
1508 static void test_schannel_provider(void)
1510 HCRYPTPROV hProv;
1511 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1512 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1513 BOOL result;
1514 DWORD dwLen;
1515 SCHANNEL_ALG saSChannelAlg;
1516 CRYPT_DATA_BLOB data_blob;
1517 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1518 BYTE abTLS1Master[140] = {
1519 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1520 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1521 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1522 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1523 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1524 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1525 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1526 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1527 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1528 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1529 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1530 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1531 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1532 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1533 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1534 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1535 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1536 0xd3, 0x1e, 0x82, 0xb3
1538 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1539 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1540 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1541 BYTE abClientFinished[16] = "client finished";
1542 BYTE abData[16] = "Wine rocks!";
1543 BYTE abMD5Hash[16];
1544 static const BYTE abEncryptedData[16] = {
1545 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1546 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1548 static const BYTE abPRF[16] = {
1549 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1550 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1552 static const BYTE abMD5[16] = {
1553 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1554 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1557 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1558 ok (result, "%08x\n", GetLastError());
1559 if (result)
1560 CryptReleaseContext(hProv, 0);
1562 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1563 ok (result, "%08x\n", GetLastError());
1564 if (!result) return;
1566 /* To get deterministic results, we import the TLS1 master secret (which
1567 * is typically generated from a random generator). Therefore, we need
1568 * an RSA key. */
1569 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1570 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1571 ok (result, "%08x\n", GetLastError());
1572 if (!result) return;
1574 dwLen = (DWORD)sizeof(abTLS1Master);
1575 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1576 ok (result, "%08x\n", GetLastError());
1577 if (!result) return;
1579 /* Setting the TLS1 client and server random parameters, as well as the
1580 * MAC and encryption algorithm parameters. */
1581 data_blob.cbData = 33;
1582 data_blob.pbData = abClientSecret;
1583 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1584 ok (result, "%08x\n", GetLastError());
1585 if (!result) return;
1587 data_blob.cbData = 33;
1588 data_blob.pbData = abServerSecret;
1589 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1590 ok (result, "%08x\n", GetLastError());
1591 if (!result) return;
1593 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1594 saSChannelAlg.Algid = CALG_DES;
1595 saSChannelAlg.cBits = 64;
1596 saSChannelAlg.dwFlags = 0;
1597 saSChannelAlg.dwReserved = 0;
1598 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1599 ok (result, "%08x\n", GetLastError());
1600 if (!result) return;
1602 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1603 saSChannelAlg.Algid = CALG_MD5;
1604 saSChannelAlg.cBits = 128;
1605 saSChannelAlg.dwFlags = 0;
1606 saSChannelAlg.dwReserved = 0;
1607 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1608 ok (result, "%08x\n", GetLastError());
1609 if (!result) return;
1611 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1612 * (Keys can only be derived from hashes, not from other keys.) */
1613 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1614 ok (result, "%08x\n", GetLastError());
1615 if (!result) return;
1617 /* Deriving the server write encryption key from the master hash */
1618 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1619 ok (result, "%08x\n", GetLastError());
1620 if (!result) return;
1622 /* Encrypting some data with the server write encryption key and checking the result. */
1623 dwLen = 12;
1624 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1625 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1627 /* Second test case: Test the TLS1 pseudo random number function. */
1628 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1629 ok (result, "%08x\n", GetLastError());
1630 if (!result) return;
1632 /* Set the label and seed parameters for the random number function */
1633 data_blob.cbData = 36;
1634 data_blob.pbData = abHashedHandshakes;
1635 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1636 ok (result, "%08x\n", GetLastError());
1637 if (!result) return;
1639 data_blob.cbData = 15;
1640 data_blob.pbData = abClientFinished;
1641 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1642 ok (result, "%08x\n", GetLastError());
1643 if (!result) return;
1645 /* Generate some pseudo random bytes and check if they are correct. */
1646 dwLen = (DWORD)sizeof(abData);
1647 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1648 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1649 "%08x\n", GetLastError());
1651 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1652 * Hash some data with the HMAC. Compare results. */
1653 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1654 ok (result, "%08x\n", GetLastError());
1655 if (!result) return;
1657 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1658 ok (result, "%08x\n", GetLastError());
1659 if (!result) return;
1661 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1662 ok (result, "%08x\n", GetLastError());
1663 if (!result) return;
1665 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1666 ok (result, "%08x\n", GetLastError());
1667 if (!result) return;
1669 dwLen = (DWORD)sizeof(abMD5Hash);
1670 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1671 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1673 CryptDestroyHash(hHMAC);
1674 CryptDestroyHash(hTLS1PRF);
1675 CryptDestroyHash(hMasterHash);
1676 CryptDestroyKey(hServerWriteMACKey);
1677 CryptDestroyKey(hServerWriteKey);
1678 CryptDestroyKey(hRSAKey);
1679 CryptDestroyKey(hMasterSecret);
1680 CryptReleaseContext(hProv, 0);
1681 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1684 static void test_enum_container(void)
1686 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
1687 DWORD dwBufferLen;
1688 BOOL result, fFound = FALSE;
1690 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1691 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1692 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1693 ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1695 /* If the result fits into abContainerName dwBufferLen is left untouched */
1696 dwBufferLen = (DWORD)sizeof(abContainerName);
1697 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1698 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1700 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1701 do {
1702 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1703 dwBufferLen = (DWORD)sizeof(abContainerName);
1704 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1706 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1709 static BYTE signBlob[] = {
1710 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1711 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1712 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1713 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1714 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1715 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1716 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1717 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1718 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1719 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1720 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1721 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1722 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1723 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1724 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1725 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1726 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1727 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1728 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1729 0xb6,0x85,0x86,0x07 };
1731 static void test_null_provider(void)
1733 HCRYPTPROV prov;
1734 HCRYPTKEY key;
1735 BOOL result;
1736 DWORD keySpec, dataLen,dwParam;
1737 char szName[MAX_PATH];
1739 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1740 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1741 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1742 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1743 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1744 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1745 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1746 CRYPT_DELETEKEYSET);
1747 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1748 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1749 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1750 CRYPT_DELETEKEYSET);
1751 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1752 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1753 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1754 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1755 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1757 /* Delete the default container. */
1758 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1759 /* Once you've deleted the default container you can't open it as if it
1760 * already exists.
1762 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1763 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1764 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1765 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1766 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1767 CRYPT_VERIFYCONTEXT);
1768 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1769 if (!result) return;
1770 dataLen = sizeof(keySpec);
1771 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1772 if (result)
1773 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1774 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1775 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1776 * supported, you can't get the keys from this container.
1778 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1779 ok(!result && GetLastError() == NTE_NO_KEY,
1780 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1781 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1782 ok(!result && GetLastError() == NTE_NO_KEY,
1783 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1784 result = CryptReleaseContext(prov, 0);
1785 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1786 /* You can create a new default container. */
1787 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1788 CRYPT_NEWKEYSET);
1789 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1790 /* But you still can't get the keys (until one's been generated.) */
1791 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1792 ok(!result && GetLastError() == NTE_NO_KEY,
1793 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1794 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1795 ok(!result && GetLastError() == NTE_NO_KEY,
1796 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1797 CryptReleaseContext(prov, 0);
1798 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1800 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1801 CRYPT_DELETEKEYSET);
1802 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1803 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1804 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1805 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1806 CRYPT_VERIFYCONTEXT);
1807 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1808 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1809 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1810 CRYPT_NEWKEYSET);
1811 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1812 if (!result) return;
1813 /* Test provider parameters getter */
1814 dataLen = sizeof(dwParam);
1815 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1816 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1817 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1818 dataLen = sizeof(dwParam);
1819 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1820 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1821 "Expected 0, got 0x%08X\n",dwParam);
1822 dataLen = sizeof(dwParam);
1823 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1824 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1825 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1826 dataLen = sizeof(keySpec);
1827 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1828 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1829 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1830 /* PP_CONTAINER parameter */
1831 dataLen = sizeof(szName);
1832 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1833 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1834 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1835 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1836 /* PP_UNIQUE_CONTAINER parameter */
1837 dataLen = sizeof(szName);
1838 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1839 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1840 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1841 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1842 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1843 ok(!result && GetLastError() == NTE_NO_KEY,
1844 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1845 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1846 ok(!result && GetLastError() == NTE_NO_KEY,
1847 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1849 /* Importing a key exchange blob.. */
1850 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1851 0, 0, &key);
1852 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1853 CryptDestroyKey(key);
1854 /* allows access to the key exchange key.. */
1855 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1856 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1857 CryptDestroyKey(key);
1858 /* but not to the private key. */
1859 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1860 ok(!result && GetLastError() == NTE_NO_KEY,
1861 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1862 CryptReleaseContext(prov, 0);
1863 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1864 CRYPT_DELETEKEYSET);
1866 /* Whereas importing a sign blob.. */
1867 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1868 CRYPT_NEWKEYSET);
1869 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1870 if (!result) return;
1871 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1872 ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1873 CryptDestroyKey(key);
1874 /* doesn't allow access to the key exchange key.. */
1875 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1876 ok(!result && GetLastError() == NTE_NO_KEY,
1877 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1878 /* but does to the private key. */
1879 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1880 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1881 CryptDestroyKey(key);
1882 CryptReleaseContext(prov, 0);
1884 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1885 CRYPT_DELETEKEYSET);
1888 /* test for the bug in accessing the user key in a container
1890 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1891 CRYPT_NEWKEYSET);
1892 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1893 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1894 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1895 CryptDestroyKey(key);
1896 CryptReleaseContext(prov,0);
1897 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1898 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1899 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1900 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1901 CryptDestroyKey(key);
1902 CryptReleaseContext(prov, 0);
1904 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1905 CRYPT_DELETEKEYSET);
1907 /* test the machine key set */
1908 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1909 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1910 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1911 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1912 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1913 CryptReleaseContext(prov, 0);
1914 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1915 CRYPT_MACHINE_KEYSET);
1916 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1917 CryptReleaseContext(prov,0);
1918 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1919 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1920 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1921 GetLastError());
1922 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1923 CRYPT_MACHINE_KEYSET);
1924 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1925 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1929 START_TEST(rsaenh)
1931 if (!init_base_environment())
1932 return;
1933 test_prov();
1934 test_gen_random();
1935 test_hashes();
1936 test_rc4();
1937 test_rc2();
1938 test_des();
1939 test_3des112();
1940 test_3des();
1941 test_hmac();
1942 test_mac();
1943 test_block_cipher_modes();
1944 test_import_private();
1945 test_verify_signature();
1946 test_rsa_encrypt();
1947 test_import_export();
1948 test_enum_container();
1949 clean_up_base_environment();
1950 test_schannel_provider();
1951 test_null_provider();
1952 if (!init_aes_environment())
1953 return;
1954 test_aes(128);
1955 test_aes(192);
1956 test_aes(256);
1957 clean_up_aes_environment();