rsaenh: Fix some leaks of the provider handle in the rsaenh tests.
[wine.git] / dlls / rsaenh / tests / rsaenh.c
blob4b3176cf46858317d8cd373e9b662f65b86b5ceb
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());
482 static void test_3des112(void)
484 HCRYPTKEY hKey;
485 BOOL result;
486 DWORD dwLen;
487 unsigned char pbData[16];
488 int i;
490 result = derive_key(CALG_3DES_112, &hKey, 0);
491 if (!result) {
492 /* rsaenh compiled without OpenSSL */
493 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
494 return;
497 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
499 dwLen = 13;
500 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
501 ok(result, "%08x\n", GetLastError());
503 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
504 ok(result, "%08x\n", GetLastError());
506 for (i=0; i<4; i++)
508 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
510 dwLen = cTestData[i].enclen;
511 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
512 ok(result, "%08x\n", GetLastError());
513 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
515 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
516 ok(result, "%08x\n", GetLastError());
517 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
518 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
519 if((dwLen != cTestData[i].enclen) ||
520 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
522 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
523 printBytes("got",pbData,dwLen);
526 result = CryptDestroyKey(hKey);
527 ok(result, "%08x\n", GetLastError());
530 static void test_des(void)
532 HCRYPTKEY hKey;
533 BOOL result;
534 DWORD dwLen, dwMode;
535 unsigned char pbData[16];
536 int i;
538 result = derive_key(CALG_DES, &hKey, 56);
539 if (!result) {
540 /* rsaenh compiled without OpenSSL */
541 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
542 return;
545 dwMode = CRYPT_MODE_ECB;
546 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
547 ok(result, "%08x\n", GetLastError());
549 dwLen = sizeof(DWORD);
550 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
551 ok(result, "%08x\n", GetLastError());
553 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
555 dwLen = 13;
556 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
557 ok(result, "%08x\n", GetLastError());
559 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
560 ok(result, "%08x\n", GetLastError());
562 for (i=0; i<4; i++)
564 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
566 dwLen = cTestData[i].enclen;
567 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
568 ok(result, "%08x\n", GetLastError());
569 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
571 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
572 ok(result, "%08x\n", GetLastError());
573 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
574 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
575 if((dwLen != cTestData[i].enclen) ||
576 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
578 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
579 printBytes("got",pbData,dwLen);
583 result = CryptDestroyKey(hKey);
584 ok(result, "%08x\n", GetLastError());
587 static void test_3des(void)
589 HCRYPTKEY hKey;
590 BOOL result;
591 DWORD dwLen;
592 unsigned char pbData[16];
593 static const BYTE des3[16] = {
594 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
595 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
596 int i;
598 result = derive_key(CALG_3DES, &hKey, 0);
599 if (!result) return;
601 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
603 dwLen = 13;
604 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
605 ok(result, "%08x\n", GetLastError());
607 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
609 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
610 ok(result, "%08x\n", GetLastError());
612 for (i=0; i<4; i++)
614 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
616 dwLen = cTestData[i].enclen;
617 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
618 ok(result, "%08x\n", GetLastError());
619 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
621 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
622 ok(result, "%08x\n", GetLastError());
623 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
624 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
625 if((dwLen != cTestData[i].enclen) ||
626 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
628 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
629 printBytes("got",pbData,dwLen);
632 result = CryptDestroyKey(hKey);
633 ok(result, "%08x\n", GetLastError());
636 static void test_aes(int keylen)
638 HCRYPTKEY hKey;
639 BOOL result;
640 DWORD dwLen;
641 unsigned char pbData[16];
642 int i;
644 switch (keylen)
646 case 256:
647 result = derive_key(CALG_AES_256, &hKey, 0);
648 break;
649 case 192:
650 result = derive_key(CALG_AES_192, &hKey, 0);
651 break;
652 default:
653 case 128:
654 result = derive_key(CALG_AES_128, &hKey, 0);
655 break;
657 if (!result) return;
659 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
661 dwLen = 13;
662 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
663 ok(result, "%08x\n", GetLastError());
665 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
666 ok(result, "%08x\n", GetLastError());
668 for (i=0; i<4; i++)
670 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
672 dwLen = cTestData[i].enclen;
673 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
674 ok(result, "%08x\n", GetLastError());
675 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
677 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
678 ok(result, "%08x\n", GetLastError());
679 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
680 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
681 if((dwLen != cTestData[i].enclen) ||
682 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
684 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
685 printBytes("got",pbData,dwLen);
688 result = CryptDestroyKey(hKey);
689 ok(result, "%08x\n", GetLastError());
692 static void test_rc2(void)
694 static const BYTE rc2encrypted[16] = {
695 0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
696 0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
697 static const BYTE rc2_128_encrypted[] = {
698 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
699 0xb6,0x66 };
700 HCRYPTHASH hHash;
701 HCRYPTKEY hKey;
702 BOOL result;
703 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
704 BYTE *pbTemp;
705 unsigned char pbData[2000], pbHashValue[16];
706 int i;
708 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
710 /* MD2 Hashing */
711 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
712 if (!result) {
713 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
714 } else {
715 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
716 ok(result, "%08x\n", GetLastError());
718 dwLen = 16;
719 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
720 ok(result, "%08x\n", GetLastError());
722 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
723 ok(result, "%08x\n", GetLastError());
725 dwLen = sizeof(DWORD);
726 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
727 ok(result, "%08x\n", GetLastError());
729 dwMode = CRYPT_MODE_CBC;
730 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
731 ok(result, "%08x\n", GetLastError());
733 dwLen = sizeof(DWORD);
734 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
735 ok(result, "%08x\n", GetLastError());
737 dwLen = sizeof(DWORD);
738 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
739 ok(result, "%08x\n", GetLastError());
741 dwLen = sizeof(DWORD);
742 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
743 ok(result, "%08x\n", GetLastError());
745 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
746 ok(result, "%08x\n", GetLastError());
747 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
748 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
749 HeapFree(GetProcessHeap(), 0, pbTemp);
751 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
752 ok(result, "%08x\n", GetLastError());
753 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
754 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
755 HeapFree(GetProcessHeap(), 0, pbTemp);
757 dwLen = sizeof(DWORD);
758 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
760 result = CryptDestroyHash(hHash);
761 ok(result, "%08x\n", GetLastError());
763 dwDataLen = 13;
764 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
765 ok(result, "%08x\n", GetLastError());
767 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
769 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
770 ok(result, "%08x\n", GetLastError());
771 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
772 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
773 HeapFree(GetProcessHeap(), 0, pbTemp);
775 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
776 ok(result, "%08x\n", GetLastError());
778 result = CryptDestroyKey(hKey);
779 ok(result, "%08x\n", GetLastError());
782 /* Again, but test setting the effective key len */
783 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
785 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
786 if (!result) {
787 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
788 } else {
789 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
790 ok(result, "%08x\n", GetLastError());
792 dwLen = 16;
793 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
794 ok(result, "%08x\n", GetLastError());
796 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
797 ok(result, "%08x\n", GetLastError());
799 SetLastError(0xdeadbeef);
800 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
801 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
802 dwKeyLen = 0;
803 SetLastError(0xdeadbeef);
804 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
805 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
806 dwKeyLen = 1025;
807 SetLastError(0xdeadbeef);
808 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
810 dwLen = sizeof(dwKeyLen);
811 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
812 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
813 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
814 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
816 dwKeyLen = 128;
817 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
818 ok(result, "%d\n", GetLastError());
820 dwLen = sizeof(dwKeyLen);
821 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
822 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
823 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
824 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
826 result = CryptDestroyHash(hHash);
827 ok(result, "%08x\n", GetLastError());
829 dwDataLen = 13;
830 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
831 ok(result, "%08x\n", GetLastError());
833 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
834 "RC2 encryption failed!\n");
836 /* Oddly enough this succeeds, though it should have no effect */
837 dwKeyLen = 40;
838 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
839 ok(result, "%d\n", GetLastError());
841 result = CryptDestroyKey(hKey);
842 ok(result, "%08x\n", GetLastError());
846 static void test_rc4(void)
848 static const BYTE rc4[16] = {
849 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
850 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
851 BOOL result;
852 HCRYPTHASH hHash;
853 HCRYPTKEY hKey;
854 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
855 unsigned char pbData[2000], *pbTemp;
856 unsigned char pszBuffer[256];
857 int i;
859 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
861 /* MD2 Hashing */
862 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
863 if (!result) {
864 /* rsaenh compiled without OpenSSL */
865 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
866 } else {
867 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
868 ok(result, "%08x\n", GetLastError());
870 dwLen = 16;
871 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
872 ok(result, "%08x\n", GetLastError());
874 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
875 ok(result, "%08x\n", GetLastError());
877 dwLen = sizeof(DWORD);
878 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
879 ok(result, "%08x\n", GetLastError());
881 dwLen = sizeof(DWORD);
882 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
883 ok(result, "%08x\n", GetLastError());
885 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
886 ok(result, "%08x\n", GetLastError());
887 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
888 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
889 HeapFree(GetProcessHeap(), 0, pbTemp);
891 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
892 ok(result, "%08x\n", GetLastError());
893 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
894 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
895 HeapFree(GetProcessHeap(), 0, pbTemp);
897 dwLen = sizeof(DWORD);
898 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
900 result = CryptDestroyHash(hHash);
901 ok(result, "%08x\n", GetLastError());
903 dwDataLen = 16;
904 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
905 ok(result, "%08x\n", GetLastError());
906 dwDataLen = 16;
907 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
908 ok(result, "%08x\n", GetLastError());
910 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
912 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
913 ok(result, "%08x\n", GetLastError());
915 result = CryptDestroyKey(hKey);
916 ok(result, "%08x\n", GetLastError());
920 static void test_hmac(void) {
921 HCRYPTKEY hKey;
922 HCRYPTHASH hHash;
923 BOOL result;
924 /* Using CALG_MD2 here fails on Windows 2003, why ? */
925 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
926 DWORD dwLen;
927 BYTE abData[256];
928 static const BYTE hmac[16] = {
929 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
930 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
931 int i;
933 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
935 if (!derive_key(CALG_RC2, &hKey, 56)) return;
937 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
938 ok(result, "%08x\n", GetLastError());
939 if (!result) return;
941 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
942 ok(result, "%08x\n", GetLastError());
944 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
945 ok(result, "%08x\n", GetLastError());
947 dwLen = sizeof(abData)/sizeof(BYTE);
948 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
949 ok(result, "%08x\n", GetLastError());
951 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
953 result = CryptDestroyHash(hHash);
954 ok(result, "%08x\n", GetLastError());
956 result = CryptDestroyKey(hKey);
957 ok(result, "%08x\n", GetLastError());
959 /* Provoke errors */
960 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
961 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
964 static void test_mac(void) {
965 HCRYPTKEY hKey;
966 HCRYPTHASH hHash;
967 BOOL result;
968 DWORD dwLen;
969 BYTE abData[256], abEnc[264];
970 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
971 int i;
973 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
974 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
976 if (!derive_key(CALG_RC2, &hKey, 56)) return;
978 dwLen = 256;
979 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
980 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
982 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
983 ok(result, "%08x\n", GetLastError());
984 if (!result) return;
986 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
987 ok(result, "%08x\n", GetLastError());
989 dwLen = sizeof(abData)/sizeof(BYTE);
990 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
991 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
993 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
995 result = CryptDestroyHash(hHash);
996 ok(result, "%08x\n", GetLastError());
998 result = CryptDestroyKey(hKey);
999 ok(result, "%08x\n", GetLastError());
1001 /* Provoke errors */
1002 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1004 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1005 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1007 result = CryptDestroyKey(hKey);
1008 ok(result, "%08x\n", GetLastError());
1011 static BYTE abPlainPrivateKey[596] = {
1012 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1013 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1014 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1015 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1016 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1017 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1018 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1019 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1020 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1021 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1022 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1023 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1024 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1025 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1026 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1027 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1028 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1029 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1030 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1031 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1032 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1033 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1034 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1035 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1036 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1037 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1038 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1039 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1040 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1041 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1042 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1043 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1044 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1045 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1046 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1047 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1048 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1049 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1050 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1051 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1052 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1053 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1054 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1055 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1056 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1057 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1058 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1059 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1060 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1061 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1062 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1063 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1064 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1065 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1066 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1067 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1068 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1069 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1070 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1071 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1072 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1073 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1074 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1075 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1076 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1077 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1078 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1079 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1080 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1081 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1082 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1083 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1084 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1085 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1086 0xf2, 0x5d, 0x58, 0x07
1089 static void test_import_private(void)
1091 DWORD dwLen;
1092 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1093 BOOL result;
1094 static BYTE abSessionKey[148] = {
1095 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1096 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1097 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1098 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1099 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1100 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1101 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1102 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1103 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1104 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1105 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1106 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1107 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1108 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1109 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1110 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1111 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1112 0x04, 0x8c, 0x49, 0x92
1114 static BYTE abEncryptedMessage[12] = {
1115 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1116 0x1c, 0xfd, 0xde, 0x71
1119 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1120 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1121 if (!result) {
1122 /* rsaenh compiled without OpenSSL */
1123 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1124 return;
1127 dwLen = (DWORD)sizeof(abSessionKey);
1128 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1129 ok(result, "%08x\n", GetLastError());
1130 if (!result) return;
1132 dwLen = (DWORD)sizeof(abEncryptedMessage);
1133 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1134 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1135 "%08x, len: %d\n", GetLastError(), dwLen);
1137 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1139 dwLen = (DWORD)sizeof(abSessionKey);
1140 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1141 ok(result, "%08x\n", GetLastError());
1142 if (!result) return;
1144 dwLen = (DWORD)sizeof(abSessionKey);
1145 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1146 ok(result, "%08x\n", GetLastError());
1147 if (!result) return;
1150 static void test_verify_signature(void) {
1151 HCRYPTHASH hHash;
1152 HCRYPTKEY hPubSignKey;
1153 BYTE abData[] = "Wine rocks!";
1154 BOOL result;
1155 BYTE abPubKey[148] = {
1156 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1157 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1158 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1159 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1160 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1161 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1162 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1163 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1164 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1165 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1166 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1167 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1168 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1169 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1170 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1171 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1172 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1173 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1174 0xe1, 0x21, 0x50, 0xac
1176 /* md2 with hash oid */
1177 BYTE abSignatureMD2[128] = {
1178 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1179 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1180 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1181 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1182 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1183 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1184 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1185 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1186 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1187 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1188 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1189 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1190 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1191 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1192 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1193 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1195 /* md2 without hash oid */
1196 BYTE abSignatureMD2NoOID[128] = {
1197 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1198 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1199 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1200 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1201 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1202 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1203 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1204 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1205 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1206 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1207 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1208 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1209 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1210 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1211 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1212 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1214 /* md4 with hash oid */
1215 BYTE abSignatureMD4[128] = {
1216 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1217 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1218 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1219 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1220 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1221 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1222 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1223 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1224 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1225 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1226 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1227 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1228 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1229 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1230 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1231 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1233 /* md4 without hash oid */
1234 BYTE abSignatureMD4NoOID[128] = {
1235 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1236 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1237 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1238 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1239 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1240 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1241 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1242 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1243 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1244 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1245 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1246 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1247 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1248 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1249 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1250 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1252 /* md5 with hash oid */
1253 BYTE abSignatureMD5[128] = {
1254 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1255 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1256 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1257 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1258 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1259 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1260 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1261 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1262 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1263 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1264 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1265 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1266 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1267 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1268 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1269 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1271 /* md5 without hash oid */
1272 BYTE abSignatureMD5NoOID[128] = {
1273 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1274 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1275 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1276 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1277 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1278 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1279 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1280 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1281 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1282 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1283 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1284 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1285 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1286 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1287 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1288 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1290 /* sha with hash oid */
1291 BYTE abSignatureSHA[128] = {
1292 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1293 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1294 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1295 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1296 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1297 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1298 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1299 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1300 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1301 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1302 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1303 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1304 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1305 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1306 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1307 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1309 /* sha without hash oid */
1310 BYTE abSignatureSHANoOID[128] = {
1311 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1312 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1313 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1314 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1315 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1316 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1317 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1318 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1319 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1320 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1321 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1322 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1323 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1324 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1325 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1326 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1329 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1330 ok(result, "%08x\n", GetLastError());
1331 if (!result) return;
1333 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1334 ok(result, "%08x\n", GetLastError());
1335 if (!result) return;
1337 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1338 ok(result, "%08x\n", GetLastError());
1339 if (!result) return;
1341 /*check that a NULL pointer signature is correctly handled*/
1342 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1343 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1344 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1345 if (result) return;
1347 /* check that we get a bad signature error when the signature is too short*/
1348 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1349 ok(!result && NTE_BAD_SIGNATURE == GetLastError(),
1350 "Expected NTE_BAD_SIGNATURE error, got %08x\n", GetLastError());
1351 if (result) return;
1353 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1354 ok(result, "%08x\n", GetLastError());
1355 if (!result) return;
1357 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1358 ok(result, "%08x\n", GetLastError());
1359 if (!result) return;
1361 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1362 * the OID at all. */
1363 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1364 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1365 if (result) return;*/
1367 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1368 ok(result, "%08x\n", GetLastError());
1369 if (!result) return;
1371 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1372 ok(result, "%08x\n", GetLastError());
1373 if (!result) return;
1375 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1376 ok(result, "%08x\n", GetLastError());
1377 if (!result) return;
1379 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1380 ok(result, "%08x\n", GetLastError());
1381 if (!result) return;
1383 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1384 ok(result, "%08x\n", GetLastError());
1385 if (!result) return;
1387 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1388 ok(result, "%08x\n", GetLastError());
1389 if (!result) return;
1391 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1392 ok(result, "%08x\n", GetLastError());
1393 if (!result) return;
1395 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1396 ok(result, "%08x\n", GetLastError());
1397 if (!result) return;
1399 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1400 ok(result, "%08x\n", GetLastError());
1401 if (!result) return;
1403 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1404 ok(result, "%08x\n", GetLastError());
1405 if (!result) return;
1407 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1408 ok(result, "%08x\n", GetLastError());
1409 if (!result) return;
1411 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1412 ok(result, "%08x\n", GetLastError());
1413 if (!result) return;
1416 static void test_rsa_encrypt(void)
1418 HCRYPTKEY hRSAKey;
1419 BYTE abData[2048] = "Wine rocks!";
1420 BOOL result;
1421 DWORD dwLen;
1423 /* It is allowed to use the key exchange key for encryption/decryption */
1424 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1425 ok (result, "%08x\n", GetLastError());
1426 if (!result) return;
1428 dwLen = 12;
1429 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1430 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1431 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1432 dwLen = 12;
1433 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1434 ok (result, "%08x\n", GetLastError());
1435 if (!result) return;
1437 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1438 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1440 CryptDestroyKey(hRSAKey);
1442 /* It is not allowed to use the signature key for encryption/decryption */
1443 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1444 ok (result, "%08x\n", GetLastError());
1445 if (!result) return;
1447 dwLen = 12;
1448 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1449 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1451 CryptDestroyKey(hRSAKey);
1454 static void test_import_export(void)
1456 DWORD dwLen, dwDataLen;
1457 HCRYPTKEY hPublicKey;
1458 BOOL result;
1459 ALG_ID algID;
1460 BYTE emptyKey[2048];
1461 static BYTE abPlainPublicKey[84] = {
1462 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1463 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1464 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1465 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1466 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1467 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1468 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1469 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1470 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1471 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1472 0x11, 0x11, 0x11, 0x11
1475 dwLen=84;
1476 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1477 ok(result, "failed to import the public key\n");
1479 dwDataLen=sizeof(algID);
1480 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1481 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1482 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1484 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1485 ok(result, "failed to export the fresh imported public key\n");
1486 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1487 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1490 static void test_schannel_provider(void)
1492 HCRYPTPROV hProv;
1493 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1494 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1495 BOOL result;
1496 DWORD dwLen;
1497 SCHANNEL_ALG saSChannelAlg;
1498 CRYPT_DATA_BLOB data_blob;
1499 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1500 BYTE abPlainPrivateKey[596] = {
1501 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1502 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1503 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1504 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1505 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1506 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1507 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1508 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1509 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1510 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1511 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1512 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1513 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1514 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1515 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1516 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1517 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1518 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1519 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1520 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1521 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1522 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1523 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1524 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1525 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1526 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1527 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1528 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1529 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1530 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1531 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1532 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1533 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1534 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1535 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1536 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1537 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1538 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1539 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1540 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1541 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1542 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1543 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1544 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1545 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1546 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1547 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1548 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1549 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1550 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1551 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1552 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1553 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1554 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1555 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1556 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1557 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1558 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1559 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1560 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1561 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1562 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1563 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1564 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1565 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1566 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1567 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1568 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1569 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1570 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1571 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1572 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1573 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1574 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1575 0xf2, 0x5d, 0x58, 0x07
1577 BYTE abTLS1Master[140] = {
1578 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1579 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1580 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1581 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1582 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1583 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1584 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1585 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1586 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1587 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1588 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1589 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1590 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1591 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1592 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1593 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1594 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1595 0xd3, 0x1e, 0x82, 0xb3
1597 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1598 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1599 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1600 BYTE abClientFinished[16] = "client finished";
1601 BYTE abData[16] = "Wine rocks!";
1602 BYTE abMD5Hash[16];
1603 static const BYTE abEncryptedData[16] = {
1604 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1605 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1607 static const BYTE abPRF[16] = {
1608 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1609 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1611 static const BYTE abMD5[16] = {
1612 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1613 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1616 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1617 ok (result, "%08x\n", GetLastError());
1618 if (result)
1619 CryptReleaseContext(hProv, 0);
1621 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1622 ok (result, "%08x\n", GetLastError());
1623 if (!result) return;
1625 /* To get deterministic results, we import the TLS1 master secret (which
1626 * is typically generated from a random generator). Therefore, we need
1627 * an RSA key. */
1628 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1629 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1630 ok (result, "%08x\n", GetLastError());
1631 if (!result) return;
1633 dwLen = (DWORD)sizeof(abTLS1Master);
1634 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1635 ok (result, "%08x\n", GetLastError());
1636 if (!result) return;
1638 /* Setting the TLS1 client and server random parameters, as well as the
1639 * MAC and encryption algorithm parameters. */
1640 data_blob.cbData = 33;
1641 data_blob.pbData = abClientSecret;
1642 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1643 ok (result, "%08x\n", GetLastError());
1644 if (!result) return;
1646 data_blob.cbData = 33;
1647 data_blob.pbData = abServerSecret;
1648 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1649 ok (result, "%08x\n", GetLastError());
1650 if (!result) return;
1652 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1653 saSChannelAlg.Algid = CALG_DES;
1654 saSChannelAlg.cBits = 64;
1655 saSChannelAlg.dwFlags = 0;
1656 saSChannelAlg.dwReserved = 0;
1657 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1658 ok (result, "%08x\n", GetLastError());
1659 if (!result) return;
1661 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1662 saSChannelAlg.Algid = CALG_MD5;
1663 saSChannelAlg.cBits = 128;
1664 saSChannelAlg.dwFlags = 0;
1665 saSChannelAlg.dwReserved = 0;
1666 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1667 ok (result, "%08x\n", GetLastError());
1668 if (!result) return;
1670 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1671 * (Keys can only be derived from hashes, not from other keys.) */
1672 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1673 ok (result, "%08x\n", GetLastError());
1674 if (!result) return;
1676 /* Deriving the server write encryption key from the master hash */
1677 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1678 ok (result, "%08x\n", GetLastError());
1679 if (!result) return;
1681 /* Encrypting some data with the server write encryption key and checking the result. */
1682 dwLen = 12;
1683 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1684 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1686 /* Second test case: Test the TLS1 pseudo random number function. */
1687 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1688 ok (result, "%08x\n", GetLastError());
1689 if (!result) return;
1691 /* Set the label and seed parameters for the random number function */
1692 data_blob.cbData = 36;
1693 data_blob.pbData = abHashedHandshakes;
1694 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1695 ok (result, "%08x\n", GetLastError());
1696 if (!result) return;
1698 data_blob.cbData = 15;
1699 data_blob.pbData = abClientFinished;
1700 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1701 ok (result, "%08x\n", GetLastError());
1702 if (!result) return;
1704 /* Generate some pseudo random bytes and check if they are correct. */
1705 dwLen = (DWORD)sizeof(abData);
1706 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1707 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1708 "%08x\n", GetLastError());
1710 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1711 * Hash some data with the HMAC. Compare results. */
1712 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1713 ok (result, "%08x\n", GetLastError());
1714 if (!result) return;
1716 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1717 ok (result, "%08x\n", GetLastError());
1718 if (!result) return;
1720 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1721 ok (result, "%08x\n", GetLastError());
1722 if (!result) return;
1724 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1725 ok (result, "%08x\n", GetLastError());
1726 if (!result) return;
1728 dwLen = (DWORD)sizeof(abMD5Hash);
1729 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1730 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1732 CryptDestroyHash(hHMAC);
1733 CryptDestroyHash(hTLS1PRF);
1734 CryptDestroyHash(hMasterHash);
1735 CryptDestroyKey(hServerWriteMACKey);
1736 CryptDestroyKey(hServerWriteKey);
1737 CryptDestroyKey(hRSAKey);
1738 CryptDestroyKey(hMasterSecret);
1739 CryptReleaseContext(hProv, 0);
1740 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1743 static void test_enum_container(void)
1745 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
1746 DWORD dwBufferLen;
1747 BOOL result, fFound = FALSE;
1749 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1750 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1751 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1752 ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1754 /* If the result fits into abContainerName dwBufferLen is left untouched */
1755 dwBufferLen = (DWORD)sizeof(abContainerName);
1756 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1757 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1759 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1760 do {
1761 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1762 dwBufferLen = (DWORD)sizeof(abContainerName);
1763 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1765 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1768 static BYTE signBlob[] = {
1769 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1770 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1771 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1772 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1773 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1774 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1775 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1776 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1777 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1778 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1779 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1780 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1781 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1782 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1783 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1784 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1785 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1786 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1787 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1788 0xb6,0x85,0x86,0x07 };
1790 static void test_null_provider(void)
1792 HCRYPTPROV prov;
1793 HCRYPTKEY key;
1794 BOOL result;
1795 DWORD keySpec, dataLen,dwParam;
1796 char szName[MAX_PATH];
1798 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1799 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1800 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1801 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1802 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1803 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1804 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1805 CRYPT_DELETEKEYSET);
1806 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1807 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1808 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1809 CRYPT_DELETEKEYSET);
1810 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1811 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1812 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1813 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1814 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1816 /* Delete the default container. */
1817 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1818 /* Once you've deleted the default container you can't open it as if it
1819 * already exists.
1821 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1822 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1823 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1824 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1825 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1826 CRYPT_VERIFYCONTEXT);
1827 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1828 if (!result) return;
1829 dataLen = sizeof(keySpec);
1830 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1831 if (result)
1832 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1833 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1834 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1835 * supported, you can't get the keys from this container.
1837 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1838 ok(!result && GetLastError() == NTE_NO_KEY,
1839 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1840 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1841 ok(!result && GetLastError() == NTE_NO_KEY,
1842 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1843 result = CryptReleaseContext(prov, 0);
1844 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1845 /* You can create a new default container. */
1846 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1847 CRYPT_NEWKEYSET);
1848 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1849 /* But you still can't get the keys (until one's been generated.) */
1850 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1851 ok(!result && GetLastError() == NTE_NO_KEY,
1852 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1853 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1854 ok(!result && GetLastError() == NTE_NO_KEY,
1855 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1856 CryptReleaseContext(prov, 0);
1857 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1859 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1860 CRYPT_DELETEKEYSET);
1861 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1862 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1863 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1864 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1865 CRYPT_VERIFYCONTEXT);
1866 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1867 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1868 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1869 CRYPT_NEWKEYSET);
1870 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1871 if (!result) return;
1872 /* Test provider parameters getter */
1873 dataLen = sizeof(dwParam);
1874 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1875 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1876 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1877 dataLen = sizeof(dwParam);
1878 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1879 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1880 "Expected 0, got 0x%08X\n",dwParam);
1881 dataLen = sizeof(dwParam);
1882 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1883 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1884 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1885 dataLen = sizeof(keySpec);
1886 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1887 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1888 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1889 /* PP_CONTAINER parameter */
1890 dataLen = sizeof(szName);
1891 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1892 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1893 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1894 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1895 /* PP_UNIQUE_CONTAINER parameter */
1896 dataLen = sizeof(szName);
1897 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1898 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1899 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1900 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1901 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1902 ok(!result && GetLastError() == NTE_NO_KEY,
1903 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1904 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1905 ok(!result && GetLastError() == NTE_NO_KEY,
1906 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1908 /* Importing a key exchange blob.. */
1909 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1910 0, 0, &key);
1911 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1912 CryptDestroyKey(key);
1913 /* allows access to the key exchange key.. */
1914 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1915 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1916 CryptDestroyKey(key);
1917 /* but not to the private key. */
1918 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1919 ok(!result && GetLastError() == NTE_NO_KEY,
1920 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1921 CryptReleaseContext(prov, 0);
1922 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1923 CRYPT_DELETEKEYSET);
1925 /* Whereas importing a sign blob.. */
1926 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1927 CRYPT_NEWKEYSET);
1928 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1929 if (!result) return;
1930 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1931 ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1932 /* doesn't allow access to the key exchange key.. */
1933 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1934 ok(!result && GetLastError() == NTE_NO_KEY,
1935 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1936 /* but does to the private key. */
1937 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1938 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1939 CryptDestroyKey(key);
1940 CryptReleaseContext(prov, 0);
1942 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1943 CRYPT_DELETEKEYSET);
1946 /* test for the bug in accessing the user key in a container
1948 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1949 CRYPT_NEWKEYSET);
1950 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1951 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1952 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1953 CryptDestroyKey(key);
1954 CryptReleaseContext(prov,0);
1955 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1956 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1957 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1958 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1959 CryptDestroyKey(key);
1960 CryptReleaseContext(prov, 0);
1962 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1963 CRYPT_DELETEKEYSET);
1964 CryptReleaseContext(prov, 0);
1966 /* test the machine key set */
1967 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1968 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1969 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1970 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1971 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1972 CryptReleaseContext(prov, 0);
1973 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1974 CRYPT_MACHINE_KEYSET);
1975 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1976 CryptReleaseContext(prov,0);
1977 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1978 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1979 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1980 GetLastError());
1981 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1982 CRYPT_MACHINE_KEYSET);
1983 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1984 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1988 START_TEST(rsaenh)
1990 if (!init_base_environment())
1991 return;
1992 test_prov();
1993 test_gen_random();
1994 test_hashes();
1995 test_rc4();
1996 test_rc2();
1997 test_des();
1998 test_3des112();
1999 test_3des();
2000 test_hmac();
2001 test_mac();
2002 test_block_cipher_modes();
2003 test_import_private();
2004 test_verify_signature();
2005 test_rsa_encrypt();
2006 test_import_export();
2007 test_enum_container();
2008 clean_up_base_environment();
2009 test_schannel_provider();
2010 test_null_provider();
2011 if (!init_aes_environment())
2012 return;
2013 test_aes(128);
2014 test_aes(192);
2015 test_aes(256);
2016 clean_up_aes_environment();