gdi32: Remove redundant indentation levels in CreateFontIndirectA and CreateFontIndir...
[wine.git] / dlls / rsaenh / tests / rsaenh.c
blob5a7b47422c9f818ef29e975fd8598a80d18a080e
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 char szProvider[] = MS_ENHANCED_PROV_A;
35 typedef struct _ctdatatype {
36 unsigned char origstr[32];
37 unsigned char decstr[32];
38 int strlen;
39 int enclen;
40 int buflen;
41 } cryptdata;
43 static const cryptdata cTestData[4] = {
44 {"abcdefghijkl",
45 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
46 12,8,16},
47 {"abcdefghij",
48 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
49 10,8,16},
50 {"abcdefgh",
51 {'a','b','c','d','e','f','g','h',0},
52 8,8,16},
53 {"abcdefghijkl",
54 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
55 12,12,16}
58 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
60 size_t i;
61 printf("%s: ",heading);
62 for(i=0;i<cb;i++)
63 printf("0x%02x,",pb[i]);
64 putchar('\n');
67 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
70 static void trace_hex(BYTE *pbData, DWORD dwLen) {
71 char szTemp[256];
72 DWORD i, j;
74 for (i = 0; i < dwLen-7; i+=8) {
75 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
76 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
77 pbData[i+6], pbData[i+7]);
78 trace(szTemp);
80 for (j=0; i<dwLen; j++,i++) {
81 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
83 trace(szTemp);
87 static int init_base_environment(void)
89 HCRYPTKEY hKey;
90 BOOL result;
92 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
94 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
96 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
97 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
99 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
101 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
102 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
103 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
104 CRYPT_NEWKEYSET);
105 ok(result, "%08x\n", GetLastError());
106 if (!result) return 0;
107 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
108 ok(result, "%08x\n", GetLastError());
109 if (result) CryptDestroyKey(hKey);
110 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
111 ok(result, "%08x\n", GetLastError());
112 if (result) CryptDestroyKey(hKey);
114 return 1;
117 static void clean_up_base_environment(void)
119 BOOL result;
121 result = CryptReleaseContext(hProv, 1);
122 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
124 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
127 static int init_aes_environment(void)
129 HCRYPTKEY hKey;
130 BOOL result;
132 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
134 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
136 /* we are using NULL as provider name for RSA_AES provider as the provider
137 * names are different in Windows XP and Vista. Its different as to what
138 * its defined in the SDK on Windows XP.
139 * This provider is available on Windows XP, Windows 2003 and Vista. */
141 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
142 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
144 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
146 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
147 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
148 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
149 CRYPT_NEWKEYSET);
150 ok(result, "%08x\n", GetLastError());
151 if (!result) return 0;
152 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
153 ok(result, "%08x\n", GetLastError());
154 if (result) CryptDestroyKey(hKey);
155 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
156 ok(result, "%08x\n", GetLastError());
157 if (result) CryptDestroyKey(hKey);
159 return 1;
162 static void clean_up_aes_environment(void)
164 BOOL result;
166 result = CryptReleaseContext(hProv, 1);
167 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
169 CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
172 static void test_prov(void)
174 BOOL result;
175 DWORD dwLen, dwInc;
177 dwLen = (DWORD)sizeof(DWORD);
178 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
179 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
181 dwLen = (DWORD)sizeof(DWORD);
182 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
183 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
186 static void test_gen_random(void)
188 BOOL result;
189 BYTE rnd1[16], rnd2[16];
191 memset(rnd1, 0, sizeof(rnd1));
192 memset(rnd2, 0, sizeof(rnd2));
194 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
195 if (!result && GetLastError() == NTE_FAIL) {
196 /* rsaenh compiled without OpenSSL */
197 return;
200 ok(result, "%08x\n", GetLastError());
202 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
203 ok(result, "%08x\n", GetLastError());
205 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
208 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
210 HCRYPTHASH hHash;
211 BOOL result;
212 unsigned char pbData[2000];
213 int i;
215 *phKey = (HCRYPTKEY)NULL;
216 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
217 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
218 if (!result) {
219 /* rsaenh compiled without OpenSSL */
220 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
221 return FALSE;
223 ok(result, "%08x\n", GetLastError());
224 if (!result) return FALSE;
225 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
226 ok(result, "%08x\n", GetLastError());
227 if (!result) return FALSE;
228 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
229 ok(result, "%08x\n", GetLastError());
230 if (!result) return FALSE;
231 len = 2000;
232 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
233 ok(result, "%08x\n", GetLastError());
234 CryptDestroyHash(hHash);
235 return TRUE;
238 static void test_hashes(void)
240 static const unsigned char md2hash[16] = {
241 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
242 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
243 static const unsigned char md4hash[16] = {
244 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
245 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
246 static const unsigned char empty_md5hash[16] = {
247 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
248 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
249 static const unsigned char md5hash[16] = {
250 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
251 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
252 static const unsigned char sha1hash[20] = {
253 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
254 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
255 unsigned char pbData[2048];
256 BOOL result;
257 HCRYPTHASH hHash, hHashClone;
258 BYTE pbHashValue[36];
259 DWORD hashlen, len;
260 int i;
262 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
264 /* MD2 Hashing */
265 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
266 if (!result) {
267 /* rsaenh compiled without OpenSSL */
268 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
269 } else {
270 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
271 ok(result, "%08x\n", GetLastError());
273 len = sizeof(DWORD);
274 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
275 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
277 len = 16;
278 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
279 ok(result, "%08x\n", GetLastError());
281 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
283 result = CryptDestroyHash(hHash);
284 ok(result, "%08x\n", GetLastError());
287 /* MD4 Hashing */
288 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
289 ok(result, "%08x\n", GetLastError());
291 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
292 ok(result, "%08x\n", GetLastError());
294 len = sizeof(DWORD);
295 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
296 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
298 len = 16;
299 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
300 ok(result, "%08x\n", GetLastError());
302 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
304 result = CryptDestroyHash(hHash);
305 ok(result, "%08x\n", GetLastError());
307 /* MD5 Hashing */
308 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
309 ok(result, "%08x\n", GetLastError());
311 len = sizeof(DWORD);
312 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
313 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
315 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
316 ok(result, "%08x\n", GetLastError());
318 len = 16;
319 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
320 ok(result, "%08x\n", GetLastError());
322 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
324 result = CryptDestroyHash(hHash);
325 ok(result, "%08x\n", GetLastError());
327 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
328 ok(result, "%08x\n", GetLastError());
330 /* The hash is available even if CryptHashData hasn't been called */
331 len = 16;
332 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
333 ok(result, "%08x\n", GetLastError());
335 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
337 /* It's also stable: getting it twice results in the same value */
338 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
339 ok(result, "%08x\n", GetLastError());
341 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
343 /* Can't add data after the hash been retrieved */
344 SetLastError(0xdeadbeef);
345 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
346 ok(!result && GetLastError() == NTE_BAD_HASH_STATE, "%08x\n", GetLastError());
348 /* You can still retrieve the hash, its value just hasn't changed */
349 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
350 ok(result, "%08x\n", GetLastError());
352 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
354 result = CryptDestroyHash(hHash);
355 ok(result, "%08x\n", GetLastError());
357 /* SHA1 Hashing */
358 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
359 ok(result, "%08x\n", GetLastError());
361 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
362 ok(result, "%08x\n", GetLastError());
364 if(pCryptDuplicateHash) {
365 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
366 ok(result, "%08x\n", GetLastError());
368 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
369 ok(result, "%08x\n", GetLastError());
371 len = sizeof(DWORD);
372 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
373 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
375 len = 20;
376 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
377 ok(result, "%08x\n", GetLastError());
379 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
381 result = CryptDestroyHash(hHashClone);
382 ok(result, "%08x\n", GetLastError());
385 result = CryptDestroyHash(hHash);
386 ok(result, "%08x\n", GetLastError());
389 static void test_block_cipher_modes(void)
391 static const BYTE plain[23] = {
392 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
393 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
394 static const BYTE ecb[24] = {
395 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
396 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
397 static const BYTE cbc[24] = {
398 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
399 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
400 static const BYTE cfb[24] = {
401 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
402 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
403 HCRYPTKEY hKey;
404 BOOL result;
405 BYTE abData[24];
406 DWORD dwMode, dwLen;
408 result = derive_key(CALG_RC2, &hKey, 40);
409 if (!result) return;
411 memcpy(abData, plain, sizeof(abData));
413 dwMode = CRYPT_MODE_ECB;
414 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
415 ok(result, "%08x\n", GetLastError());
417 dwLen = 23;
418 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
419 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
420 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
422 SetLastError(ERROR_SUCCESS);
423 dwLen = 23;
424 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
425 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
426 "%08x, dwLen: %d\n", GetLastError(), dwLen);
428 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
429 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
430 "%08x, dwLen: %d\n", GetLastError(), dwLen);
432 dwMode = CRYPT_MODE_CBC;
433 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
434 ok(result, "%08x\n", GetLastError());
436 dwLen = 23;
437 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
438 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
439 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
441 dwLen = 23;
442 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
443 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
444 "%08x, dwLen: %d\n", GetLastError(), dwLen);
446 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
447 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
448 "%08x, dwLen: %d\n", GetLastError(), dwLen);
450 dwMode = CRYPT_MODE_CFB;
451 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
452 ok(result, "%08x\n", GetLastError());
454 dwLen = 16;
455 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
456 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
458 dwLen = 7;
459 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
460 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
461 "%08x, dwLen: %d\n", GetLastError(), dwLen);
463 dwLen = 8;
464 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
465 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
467 dwLen = 16;
468 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
469 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
470 "%08x, dwLen: %d\n", GetLastError(), dwLen);
472 dwMode = CRYPT_MODE_OFB;
473 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
474 ok(result, "%08x\n", GetLastError());
476 dwLen = 23;
477 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
478 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
480 CryptDestroyKey(hKey);
483 static void test_3des112(void)
485 HCRYPTKEY hKey;
486 BOOL result;
487 DWORD dwLen;
488 unsigned char pbData[16];
489 int i;
491 result = derive_key(CALG_3DES_112, &hKey, 0);
492 if (!result) {
493 /* rsaenh compiled without OpenSSL */
494 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
495 return;
498 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
500 dwLen = 13;
501 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
502 ok(result, "%08x\n", GetLastError());
504 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
505 ok(result, "%08x\n", GetLastError());
507 for (i=0; i<4; i++)
509 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
511 dwLen = cTestData[i].enclen;
512 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
513 ok(result, "%08x\n", GetLastError());
514 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
516 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
517 ok(result, "%08x\n", GetLastError());
518 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
519 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
520 if((dwLen != cTestData[i].enclen) ||
521 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
523 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
524 printBytes("got",pbData,dwLen);
527 result = CryptDestroyKey(hKey);
528 ok(result, "%08x\n", GetLastError());
531 static void test_des(void)
533 HCRYPTKEY hKey;
534 BOOL result;
535 DWORD dwLen, dwMode;
536 unsigned char pbData[16];
537 int i;
539 result = derive_key(CALG_DES, &hKey, 56);
540 if (!result) {
541 /* rsaenh compiled without OpenSSL */
542 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
543 return;
546 dwMode = CRYPT_MODE_ECB;
547 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
548 ok(result, "%08x\n", GetLastError());
550 dwLen = sizeof(DWORD);
551 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
552 ok(result, "%08x\n", GetLastError());
554 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
556 dwLen = 13;
557 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
558 ok(result, "%08x\n", GetLastError());
560 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
561 ok(result, "%08x\n", GetLastError());
563 for (i=0; i<4; i++)
565 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
567 dwLen = cTestData[i].enclen;
568 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
569 ok(result, "%08x\n", GetLastError());
570 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
572 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
573 ok(result, "%08x\n", GetLastError());
574 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
575 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
576 if((dwLen != cTestData[i].enclen) ||
577 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
579 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
580 printBytes("got",pbData,dwLen);
584 result = CryptDestroyKey(hKey);
585 ok(result, "%08x\n", GetLastError());
588 static void test_3des(void)
590 HCRYPTKEY hKey;
591 BOOL result;
592 DWORD dwLen;
593 unsigned char pbData[16];
594 static const BYTE des3[16] = {
595 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
596 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
597 int i;
599 result = derive_key(CALG_3DES, &hKey, 0);
600 if (!result) return;
602 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
604 dwLen = 13;
605 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
606 ok(result, "%08x\n", GetLastError());
608 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
610 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
611 ok(result, "%08x\n", GetLastError());
613 for (i=0; i<4; i++)
615 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
617 dwLen = cTestData[i].enclen;
618 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
619 ok(result, "%08x\n", GetLastError());
620 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
622 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
623 ok(result, "%08x\n", GetLastError());
624 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
625 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
626 if((dwLen != cTestData[i].enclen) ||
627 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
629 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
630 printBytes("got",pbData,dwLen);
633 result = CryptDestroyKey(hKey);
634 ok(result, "%08x\n", GetLastError());
637 static void test_aes(int keylen)
639 HCRYPTKEY hKey;
640 BOOL result;
641 DWORD dwLen;
642 unsigned char pbData[16];
643 int i;
645 switch (keylen)
647 case 256:
648 result = derive_key(CALG_AES_256, &hKey, 0);
649 break;
650 case 192:
651 result = derive_key(CALG_AES_192, &hKey, 0);
652 break;
653 default:
654 case 128:
655 result = derive_key(CALG_AES_128, &hKey, 0);
656 break;
658 if (!result) return;
660 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
662 dwLen = 13;
663 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
664 ok(result, "%08x\n", GetLastError());
666 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
667 ok(result, "%08x\n", GetLastError());
669 for (i=0; i<4; i++)
671 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
673 dwLen = cTestData[i].enclen;
674 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
675 ok(result, "%08x\n", GetLastError());
676 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
678 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
679 ok(result, "%08x\n", GetLastError());
680 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
681 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
682 if((dwLen != cTestData[i].enclen) ||
683 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
685 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
686 printBytes("got",pbData,dwLen);
689 result = CryptDestroyKey(hKey);
690 ok(result, "%08x\n", GetLastError());
693 static void test_rc2(void)
695 static const BYTE rc2encrypted[16] = {
696 0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
697 0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
698 static const BYTE rc2_128_encrypted[] = {
699 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
700 0xb6,0x66 };
701 HCRYPTHASH hHash;
702 HCRYPTKEY hKey;
703 BOOL result;
704 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
705 BYTE *pbTemp;
706 unsigned char pbData[2000], pbHashValue[16];
707 int i;
709 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
711 /* MD2 Hashing */
712 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
713 if (!result) {
714 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
715 } else {
716 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
717 ok(result, "%08x\n", GetLastError());
719 dwLen = 16;
720 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
721 ok(result, "%08x\n", GetLastError());
723 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
724 ok(result, "%08x\n", GetLastError());
726 dwLen = sizeof(DWORD);
727 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
728 ok(result, "%08x\n", GetLastError());
730 dwMode = CRYPT_MODE_CBC;
731 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
732 ok(result, "%08x\n", GetLastError());
734 dwLen = sizeof(DWORD);
735 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
736 ok(result, "%08x\n", GetLastError());
738 dwLen = sizeof(DWORD);
739 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
740 ok(result, "%08x\n", GetLastError());
742 dwLen = sizeof(DWORD);
743 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
744 ok(result, "%08x\n", GetLastError());
746 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
747 ok(result, "%08x\n", GetLastError());
748 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
749 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
750 HeapFree(GetProcessHeap(), 0, pbTemp);
752 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
753 ok(result, "%08x\n", GetLastError());
754 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
755 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
756 HeapFree(GetProcessHeap(), 0, pbTemp);
758 dwLen = sizeof(DWORD);
759 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
761 result = CryptDestroyHash(hHash);
762 ok(result, "%08x\n", GetLastError());
764 dwDataLen = 13;
765 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
766 ok(result, "%08x\n", GetLastError());
768 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
770 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
771 ok(result, "%08x\n", GetLastError());
772 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
773 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
774 HeapFree(GetProcessHeap(), 0, pbTemp);
776 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
777 ok(result, "%08x\n", GetLastError());
779 result = CryptDestroyKey(hKey);
780 ok(result, "%08x\n", GetLastError());
783 /* Again, but test setting the effective key len */
784 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
786 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
787 if (!result) {
788 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
789 } else {
790 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
791 ok(result, "%08x\n", GetLastError());
793 dwLen = 16;
794 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
795 ok(result, "%08x\n", GetLastError());
797 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
798 ok(result, "%08x\n", GetLastError());
800 SetLastError(0xdeadbeef);
801 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
802 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
803 dwKeyLen = 0;
804 SetLastError(0xdeadbeef);
805 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
806 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
807 dwKeyLen = 1025;
808 SetLastError(0xdeadbeef);
809 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
811 dwLen = sizeof(dwKeyLen);
812 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
813 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
814 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
815 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
817 dwKeyLen = 128;
818 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
819 ok(result, "%d\n", GetLastError());
821 dwLen = sizeof(dwKeyLen);
822 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
823 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
824 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
825 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
827 result = CryptDestroyHash(hHash);
828 ok(result, "%08x\n", GetLastError());
830 dwDataLen = 13;
831 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
832 ok(result, "%08x\n", GetLastError());
834 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
835 "RC2 encryption failed!\n");
837 /* Oddly enough this succeeds, though it should have no effect */
838 dwKeyLen = 40;
839 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
840 ok(result, "%d\n", GetLastError());
842 result = CryptDestroyKey(hKey);
843 ok(result, "%08x\n", GetLastError());
847 static void test_rc4(void)
849 static const BYTE rc4[16] = {
850 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
851 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
852 BOOL result;
853 HCRYPTHASH hHash;
854 HCRYPTKEY hKey;
855 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
856 unsigned char pbData[2000], *pbTemp;
857 unsigned char pszBuffer[256];
858 int i;
860 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
862 /* MD2 Hashing */
863 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
864 if (!result) {
865 /* rsaenh compiled without OpenSSL */
866 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
867 } else {
868 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
869 ok(result, "%08x\n", GetLastError());
871 dwLen = 16;
872 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
873 ok(result, "%08x\n", GetLastError());
875 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
876 ok(result, "%08x\n", GetLastError());
878 dwLen = sizeof(DWORD);
879 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
880 ok(result, "%08x\n", GetLastError());
882 dwLen = sizeof(DWORD);
883 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
884 ok(result, "%08x\n", GetLastError());
886 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
887 ok(result, "%08x\n", GetLastError());
888 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
889 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
890 HeapFree(GetProcessHeap(), 0, pbTemp);
892 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
893 ok(result, "%08x\n", GetLastError());
894 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
895 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
896 HeapFree(GetProcessHeap(), 0, pbTemp);
898 dwLen = sizeof(DWORD);
899 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
901 result = CryptDestroyHash(hHash);
902 ok(result, "%08x\n", GetLastError());
904 dwDataLen = 16;
905 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
906 ok(result, "%08x\n", GetLastError());
907 dwDataLen = 16;
908 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
909 ok(result, "%08x\n", GetLastError());
911 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
913 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
914 ok(result, "%08x\n", GetLastError());
916 result = CryptDestroyKey(hKey);
917 ok(result, "%08x\n", GetLastError());
921 static void test_hmac(void) {
922 HCRYPTKEY hKey;
923 HCRYPTHASH hHash;
924 BOOL result;
925 /* Using CALG_MD2 here fails on Windows 2003, why ? */
926 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
927 DWORD dwLen;
928 BYTE abData[256];
929 static const BYTE hmac[16] = {
930 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
931 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
932 int i;
934 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
936 if (!derive_key(CALG_RC2, &hKey, 56)) return;
938 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
939 ok(result, "%08x\n", GetLastError());
940 if (!result) return;
942 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
943 ok(result, "%08x\n", GetLastError());
945 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
946 ok(result, "%08x\n", GetLastError());
948 dwLen = sizeof(abData)/sizeof(BYTE);
949 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
950 ok(result, "%08x\n", GetLastError());
952 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
954 result = CryptDestroyHash(hHash);
955 ok(result, "%08x\n", GetLastError());
957 result = CryptDestroyKey(hKey);
958 ok(result, "%08x\n", GetLastError());
960 /* Provoke errors */
961 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
962 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
965 static void test_mac(void) {
966 HCRYPTKEY hKey;
967 HCRYPTHASH hHash;
968 BOOL result;
969 DWORD dwLen;
970 BYTE abData[256], abEnc[264];
971 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
972 int i;
974 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
975 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
977 if (!derive_key(CALG_RC2, &hKey, 56)) return;
979 dwLen = 256;
980 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
981 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
983 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
984 ok(result, "%08x\n", GetLastError());
985 if (!result) return;
987 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
988 ok(result, "%08x\n", GetLastError());
990 dwLen = sizeof(abData)/sizeof(BYTE);
991 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
992 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
994 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
996 result = CryptDestroyHash(hHash);
997 ok(result, "%08x\n", GetLastError());
999 result = CryptDestroyKey(hKey);
1000 ok(result, "%08x\n", GetLastError());
1002 /* Provoke errors */
1003 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1005 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1006 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1008 result = CryptDestroyKey(hKey);
1009 ok(result, "%08x\n", GetLastError());
1012 static BYTE abPlainPrivateKey[596] = {
1013 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1014 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1015 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1016 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1017 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1018 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1019 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1020 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1021 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1022 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1023 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1024 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1025 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1026 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1027 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1028 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1029 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1030 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1031 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1032 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1033 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1034 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1035 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1036 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1037 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1038 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1039 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1040 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1041 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1042 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1043 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1044 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1045 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1046 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1047 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1048 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1049 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1050 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1051 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1052 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1053 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1054 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1055 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1056 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1057 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1058 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1059 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1060 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1061 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1062 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1063 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1064 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1065 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1066 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1067 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1068 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1069 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1070 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1071 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1072 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1073 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1074 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1075 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1076 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1077 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1078 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1079 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1080 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1081 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1082 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1083 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1084 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1085 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1086 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1087 0xf2, 0x5d, 0x58, 0x07
1090 static void test_import_private(void)
1092 DWORD dwLen;
1093 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1094 BOOL result;
1095 static BYTE abSessionKey[148] = {
1096 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1097 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1098 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1099 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1100 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1101 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1102 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1103 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1104 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1105 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1106 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1107 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1108 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1109 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1110 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1111 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1112 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1113 0x04, 0x8c, 0x49, 0x92
1115 static BYTE abEncryptedMessage[12] = {
1116 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1117 0x1c, 0xfd, 0xde, 0x71
1120 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1121 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1122 if (!result) {
1123 /* rsaenh compiled without OpenSSL */
1124 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1125 return;
1128 dwLen = (DWORD)sizeof(abSessionKey);
1129 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1130 ok(result, "%08x\n", GetLastError());
1131 if (!result) return;
1133 dwLen = (DWORD)sizeof(abEncryptedMessage);
1134 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1135 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1136 "%08x, len: %d\n", GetLastError(), dwLen);
1137 CryptDestroyKey(hSessionKey);
1139 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1141 dwLen = (DWORD)sizeof(abSessionKey);
1142 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1143 ok(result, "%08x\n", GetLastError());
1144 CryptDestroyKey(hSessionKey);
1145 if (!result) return;
1147 dwLen = (DWORD)sizeof(abSessionKey);
1148 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1149 ok(result, "%08x\n", GetLastError());
1150 if (!result) return;
1152 CryptDestroyKey(hSessionKey);
1153 CryptDestroyKey(hKeyExchangeKey);
1156 static void test_verify_signature(void) {
1157 HCRYPTHASH hHash;
1158 HCRYPTKEY hPubSignKey;
1159 BYTE abData[] = "Wine rocks!";
1160 BOOL result;
1161 BYTE abPubKey[148] = {
1162 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1163 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1164 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1165 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1166 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1167 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1168 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1169 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1170 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1171 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1172 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1173 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1174 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1175 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1176 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1177 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1178 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1179 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1180 0xe1, 0x21, 0x50, 0xac
1182 /* md2 with hash oid */
1183 BYTE abSignatureMD2[128] = {
1184 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1185 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1186 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1187 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1188 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1189 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1190 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1191 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1192 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1193 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1194 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1195 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1196 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1197 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1198 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1199 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1201 /* md2 without hash oid */
1202 BYTE abSignatureMD2NoOID[128] = {
1203 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1204 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1205 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1206 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1207 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1208 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1209 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1210 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1211 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1212 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1213 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1214 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1215 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1216 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1217 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1218 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1220 /* md4 with hash oid */
1221 BYTE abSignatureMD4[128] = {
1222 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1223 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1224 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1225 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1226 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1227 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1228 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1229 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1230 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1231 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1232 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1233 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1234 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1235 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1236 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1237 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1239 /* md4 without hash oid */
1240 BYTE abSignatureMD4NoOID[128] = {
1241 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1242 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1243 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1244 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1245 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1246 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1247 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1248 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1249 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1250 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1251 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1252 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1253 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1254 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1255 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1256 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1258 /* md5 with hash oid */
1259 BYTE abSignatureMD5[128] = {
1260 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1261 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1262 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1263 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1264 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1265 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1266 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1267 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1268 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1269 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1270 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1271 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1272 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1273 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1274 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1275 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1277 /* md5 without hash oid */
1278 BYTE abSignatureMD5NoOID[128] = {
1279 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1280 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1281 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1282 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1283 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1284 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1285 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1286 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1287 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1288 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1289 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1290 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1291 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1292 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1293 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1294 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1296 /* sha with hash oid */
1297 BYTE abSignatureSHA[128] = {
1298 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1299 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1300 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1301 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1302 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1303 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1304 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1305 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1306 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1307 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1308 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1309 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1310 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1311 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1312 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1313 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1315 /* sha without hash oid */
1316 BYTE abSignatureSHANoOID[128] = {
1317 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1318 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1319 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1320 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1321 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1322 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1323 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1324 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1325 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1326 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1327 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1328 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1329 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1330 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1331 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1332 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1335 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1336 ok(result, "%08x\n", GetLastError());
1337 if (!result) return;
1339 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1340 ok(result, "%08x\n", GetLastError());
1341 if (!result) return;
1343 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1344 ok(result, "%08x\n", GetLastError());
1345 if (!result) return;
1347 /*check that a NULL pointer signature is correctly handled*/
1348 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1349 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1350 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1351 if (result) return;
1353 /* check that we get a bad signature error when the signature is too short*/
1354 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1355 ok(!result && NTE_BAD_SIGNATURE == GetLastError(),
1356 "Expected NTE_BAD_SIGNATURE error, got %08x\n", GetLastError());
1357 if (result) return;
1359 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1360 ok(result, "%08x\n", GetLastError());
1361 if (!result) return;
1363 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1364 ok(result, "%08x\n", GetLastError());
1365 if (!result) return;
1367 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1368 * the OID at all. */
1369 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1370 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1371 if (result) return;*/
1373 CryptDestroyHash(hHash);
1375 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1376 ok(result, "%08x\n", GetLastError());
1377 if (!result) return;
1379 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1380 ok(result, "%08x\n", GetLastError());
1381 if (!result) return;
1383 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1384 ok(result, "%08x\n", GetLastError());
1385 if (!result) return;
1387 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1388 ok(result, "%08x\n", GetLastError());
1389 if (!result) return;
1391 CryptDestroyHash(hHash);
1393 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1394 ok(result, "%08x\n", GetLastError());
1395 if (!result) return;
1397 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1398 ok(result, "%08x\n", GetLastError());
1399 if (!result) return;
1401 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1402 ok(result, "%08x\n", GetLastError());
1403 if (!result) return;
1405 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1406 ok(result, "%08x\n", GetLastError());
1407 if (!result) return;
1409 CryptDestroyHash(hHash);
1411 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1412 ok(result, "%08x\n", GetLastError());
1413 if (!result) return;
1415 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1416 ok(result, "%08x\n", GetLastError());
1417 if (!result) return;
1419 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1420 ok(result, "%08x\n", GetLastError());
1421 if (!result) return;
1423 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1424 ok(result, "%08x\n", GetLastError());
1425 if (!result) return;
1427 CryptDestroyHash(hHash);
1428 CryptDestroyKey(hPubSignKey);
1431 static void test_rsa_encrypt(void)
1433 HCRYPTKEY hRSAKey;
1434 BYTE abData[2048] = "Wine rocks!";
1435 BOOL result;
1436 DWORD dwLen;
1438 /* It is allowed to use the key exchange key for encryption/decryption */
1439 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1440 ok (result, "%08x\n", GetLastError());
1441 if (!result) return;
1443 dwLen = 12;
1444 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1445 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1446 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1447 dwLen = 12;
1448 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1449 ok (result, "%08x\n", GetLastError());
1450 if (!result) return;
1452 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1453 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1455 CryptDestroyKey(hRSAKey);
1457 /* It is not allowed to use the signature key for encryption/decryption */
1458 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1459 ok (result, "%08x\n", GetLastError());
1460 if (!result) return;
1462 dwLen = 12;
1463 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1464 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1466 CryptDestroyKey(hRSAKey);
1469 static void test_import_export(void)
1471 DWORD dwLen, dwDataLen;
1472 HCRYPTKEY hPublicKey;
1473 BOOL result;
1474 ALG_ID algID;
1475 BYTE emptyKey[2048];
1476 static BYTE abPlainPublicKey[84] = {
1477 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1478 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1479 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1480 0x11, 0x11, 0x11, 0x11, 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
1490 dwLen=84;
1491 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1492 ok(result, "failed to import the public key\n");
1494 dwDataLen=sizeof(algID);
1495 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1496 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1497 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1499 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1500 ok(result, "failed to export the fresh imported public key\n");
1501 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1502 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1504 CryptDestroyKey(hPublicKey);
1507 static void test_schannel_provider(void)
1509 HCRYPTPROV hProv;
1510 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1511 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1512 BOOL result;
1513 DWORD dwLen;
1514 SCHANNEL_ALG saSChannelAlg;
1515 CRYPT_DATA_BLOB data_blob;
1516 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1517 BYTE abTLS1Master[140] = {
1518 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1519 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1520 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1521 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1522 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1523 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1524 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1525 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1526 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1527 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1528 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1529 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1530 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1531 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1532 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1533 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1534 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1535 0xd3, 0x1e, 0x82, 0xb3
1537 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1538 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1539 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1540 BYTE abClientFinished[16] = "client finished";
1541 BYTE abData[16] = "Wine rocks!";
1542 BYTE abMD5Hash[16];
1543 static const BYTE abEncryptedData[16] = {
1544 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1545 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1547 static const BYTE abPRF[16] = {
1548 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1549 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1551 static const BYTE abMD5[16] = {
1552 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1553 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1556 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1557 ok (result, "%08x\n", GetLastError());
1558 if (result)
1559 CryptReleaseContext(hProv, 0);
1561 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1562 ok (result, "%08x\n", GetLastError());
1563 if (!result) return;
1565 /* To get deterministic results, we import the TLS1 master secret (which
1566 * is typically generated from a random generator). Therefore, we need
1567 * an RSA key. */
1568 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1569 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1570 ok (result, "%08x\n", GetLastError());
1571 if (!result) return;
1573 dwLen = (DWORD)sizeof(abTLS1Master);
1574 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1575 ok (result, "%08x\n", GetLastError());
1576 if (!result) return;
1578 /* Setting the TLS1 client and server random parameters, as well as the
1579 * MAC and encryption algorithm parameters. */
1580 data_blob.cbData = 33;
1581 data_blob.pbData = abClientSecret;
1582 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1583 ok (result, "%08x\n", GetLastError());
1584 if (!result) return;
1586 data_blob.cbData = 33;
1587 data_blob.pbData = abServerSecret;
1588 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1589 ok (result, "%08x\n", GetLastError());
1590 if (!result) return;
1592 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1593 saSChannelAlg.Algid = CALG_DES;
1594 saSChannelAlg.cBits = 64;
1595 saSChannelAlg.dwFlags = 0;
1596 saSChannelAlg.dwReserved = 0;
1597 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1598 ok (result, "%08x\n", GetLastError());
1599 if (!result) return;
1601 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1602 saSChannelAlg.Algid = CALG_MD5;
1603 saSChannelAlg.cBits = 128;
1604 saSChannelAlg.dwFlags = 0;
1605 saSChannelAlg.dwReserved = 0;
1606 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1607 ok (result, "%08x\n", GetLastError());
1608 if (!result) return;
1610 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1611 * (Keys can only be derived from hashes, not from other keys.) */
1612 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1613 ok (result, "%08x\n", GetLastError());
1614 if (!result) return;
1616 /* Deriving the server write encryption key from the master hash */
1617 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1618 ok (result, "%08x\n", GetLastError());
1619 if (!result) return;
1621 /* Encrypting some data with the server write encryption key and checking the result. */
1622 dwLen = 12;
1623 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1624 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1626 /* Second test case: Test the TLS1 pseudo random number function. */
1627 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1628 ok (result, "%08x\n", GetLastError());
1629 if (!result) return;
1631 /* Set the label and seed parameters for the random number function */
1632 data_blob.cbData = 36;
1633 data_blob.pbData = abHashedHandshakes;
1634 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1635 ok (result, "%08x\n", GetLastError());
1636 if (!result) return;
1638 data_blob.cbData = 15;
1639 data_blob.pbData = abClientFinished;
1640 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1641 ok (result, "%08x\n", GetLastError());
1642 if (!result) return;
1644 /* Generate some pseudo random bytes and check if they are correct. */
1645 dwLen = (DWORD)sizeof(abData);
1646 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1647 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1648 "%08x\n", GetLastError());
1650 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1651 * Hash some data with the HMAC. Compare results. */
1652 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1653 ok (result, "%08x\n", GetLastError());
1654 if (!result) return;
1656 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1657 ok (result, "%08x\n", GetLastError());
1658 if (!result) return;
1660 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1661 ok (result, "%08x\n", GetLastError());
1662 if (!result) return;
1664 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1665 ok (result, "%08x\n", GetLastError());
1666 if (!result) return;
1668 dwLen = (DWORD)sizeof(abMD5Hash);
1669 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1670 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1672 CryptDestroyHash(hHMAC);
1673 CryptDestroyHash(hTLS1PRF);
1674 CryptDestroyHash(hMasterHash);
1675 CryptDestroyKey(hServerWriteMACKey);
1676 CryptDestroyKey(hServerWriteKey);
1677 CryptDestroyKey(hRSAKey);
1678 CryptDestroyKey(hMasterSecret);
1679 CryptReleaseContext(hProv, 0);
1680 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1683 static void test_enum_container(void)
1685 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
1686 DWORD dwBufferLen;
1687 BOOL result, fFound = FALSE;
1689 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1690 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1691 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1692 ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1694 /* If the result fits into abContainerName dwBufferLen is left untouched */
1695 dwBufferLen = (DWORD)sizeof(abContainerName);
1696 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1697 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1699 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1700 do {
1701 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1702 dwBufferLen = (DWORD)sizeof(abContainerName);
1703 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1705 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1708 static BYTE signBlob[] = {
1709 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1710 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1711 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1712 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1713 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1714 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1715 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1716 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1717 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1718 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1719 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1720 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1721 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1722 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1723 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1724 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1725 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1726 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1727 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1728 0xb6,0x85,0x86,0x07 };
1730 static void test_null_provider(void)
1732 HCRYPTPROV prov;
1733 HCRYPTKEY key;
1734 BOOL result;
1735 DWORD keySpec, dataLen,dwParam;
1736 char szName[MAX_PATH];
1738 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1739 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1740 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1741 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1742 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1743 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1744 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1745 CRYPT_DELETEKEYSET);
1746 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1747 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1748 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1749 CRYPT_DELETEKEYSET);
1750 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1751 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1752 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1753 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1754 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1756 /* Delete the default container. */
1757 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1758 /* Once you've deleted the default container you can't open it as if it
1759 * already exists.
1761 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1762 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1763 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1764 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1765 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1766 CRYPT_VERIFYCONTEXT);
1767 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1768 if (!result) return;
1769 dataLen = sizeof(keySpec);
1770 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1771 if (result)
1772 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1773 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1774 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1775 * supported, you can't get the keys from this container.
1777 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1778 ok(!result && GetLastError() == NTE_NO_KEY,
1779 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1780 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1781 ok(!result && GetLastError() == NTE_NO_KEY,
1782 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1783 result = CryptReleaseContext(prov, 0);
1784 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1785 /* You can create a new default container. */
1786 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1787 CRYPT_NEWKEYSET);
1788 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1789 /* But you still can't get the keys (until one's been generated.) */
1790 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1791 ok(!result && GetLastError() == NTE_NO_KEY,
1792 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1793 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1794 ok(!result && GetLastError() == NTE_NO_KEY,
1795 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1796 CryptReleaseContext(prov, 0);
1797 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1799 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1800 CRYPT_DELETEKEYSET);
1801 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1802 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1803 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1804 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1805 CRYPT_VERIFYCONTEXT);
1806 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1807 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1808 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1809 CRYPT_NEWKEYSET);
1810 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1811 if (!result) return;
1812 /* Test provider parameters getter */
1813 dataLen = sizeof(dwParam);
1814 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1815 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1816 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1817 dataLen = sizeof(dwParam);
1818 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1819 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1820 "Expected 0, got 0x%08X\n",dwParam);
1821 dataLen = sizeof(dwParam);
1822 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1823 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1824 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1825 dataLen = sizeof(keySpec);
1826 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1827 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1828 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1829 /* PP_CONTAINER parameter */
1830 dataLen = sizeof(szName);
1831 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1832 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1833 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1834 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1835 /* PP_UNIQUE_CONTAINER parameter */
1836 dataLen = sizeof(szName);
1837 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1838 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1839 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1840 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1841 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1842 ok(!result && GetLastError() == NTE_NO_KEY,
1843 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1844 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1845 ok(!result && GetLastError() == NTE_NO_KEY,
1846 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1848 /* Importing a key exchange blob.. */
1849 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1850 0, 0, &key);
1851 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1852 CryptDestroyKey(key);
1853 /* allows access to the key exchange key.. */
1854 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1855 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1856 CryptDestroyKey(key);
1857 /* but not to the private key. */
1858 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1859 ok(!result && GetLastError() == NTE_NO_KEY,
1860 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1861 CryptReleaseContext(prov, 0);
1862 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1863 CRYPT_DELETEKEYSET);
1865 /* Whereas importing a sign blob.. */
1866 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1867 CRYPT_NEWKEYSET);
1868 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1869 if (!result) return;
1870 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1871 ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1872 CryptDestroyKey(key);
1873 /* doesn't allow access to the key exchange key.. */
1874 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1875 ok(!result && GetLastError() == NTE_NO_KEY,
1876 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1877 /* but does to the private key. */
1878 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1879 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1880 CryptDestroyKey(key);
1881 CryptReleaseContext(prov, 0);
1883 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1884 CRYPT_DELETEKEYSET);
1887 /* test for the bug in accessing the user key in a container
1889 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1890 CRYPT_NEWKEYSET);
1891 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1892 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1893 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1894 CryptDestroyKey(key);
1895 CryptReleaseContext(prov,0);
1896 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1897 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1898 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1899 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1900 CryptDestroyKey(key);
1901 CryptReleaseContext(prov, 0);
1903 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1904 CRYPT_DELETEKEYSET);
1906 /* test the machine key set */
1907 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1908 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1909 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1910 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1911 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1912 CryptReleaseContext(prov, 0);
1913 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1914 CRYPT_MACHINE_KEYSET);
1915 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1916 CryptReleaseContext(prov,0);
1917 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1918 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1919 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1920 GetLastError());
1921 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1922 CRYPT_MACHINE_KEYSET);
1923 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1924 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1928 START_TEST(rsaenh)
1930 if (!init_base_environment())
1931 return;
1932 test_prov();
1933 test_gen_random();
1934 test_hashes();
1935 test_rc4();
1936 test_rc2();
1937 test_des();
1938 test_3des112();
1939 test_3des();
1940 test_hmac();
1941 test_mac();
1942 test_block_cipher_modes();
1943 test_import_private();
1944 test_verify_signature();
1945 test_rsa_encrypt();
1946 test_import_export();
1947 test_enum_container();
1948 clean_up_base_environment();
1949 test_schannel_provider();
1950 test_null_provider();
1951 if (!init_aes_environment())
1952 return;
1953 test_aes(128);
1954 test_aes(192);
1955 test_aes(256);
1956 clean_up_aes_environment();