rsaenh/tests: Fix a couple typos.
[wine.git] / dlls / rsaenh / tests / rsaenh.c
blob4a694831982ada758777beb43ac7280ee0c6a8e1
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"
30 #include "winreg.h"
32 static HCRYPTPROV hProv;
33 static const char szContainer[] = "winetest";
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}
60 * 1. Take the MD5 Hash of the container name (with an extra null byte)
61 * 2. Turn the hash into a 4 DWORD hex value
62 * 3. Append a '_'
63 * 4. Add the MachineGuid
66 static void uniquecontainer(char *unique)
68 /* MD5 hash of "winetest\0" in 4 DWORD hex */
69 static const char szContainer_md5[] = "9d20fd8d05ed2b8455d125d0bf6d6a70";
70 static const char szCryptography[] = "Software\\Microsoft\\Cryptography";
71 static const char szMachineGuid[] = "MachineGuid";
72 HKEY hkey;
73 char guid[MAX_PATH];
74 DWORD size = MAX_PATH;
76 /* Get the MachineGUID */
77 RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
78 RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
79 RegCloseKey(hkey);
81 lstrcpy(unique, szContainer_md5);
82 lstrcat(unique, "_");
83 lstrcat(unique, guid);
86 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
88 size_t i;
89 printf("%s: ",heading);
90 for(i=0;i<cb;i++)
91 printf("0x%02x,",pb[i]);
92 putchar('\n');
95 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
98 static void trace_hex(BYTE *pbData, DWORD dwLen) {
99 char szTemp[256];
100 DWORD i, j;
102 for (i = 0; i < dwLen-7; i+=8) {
103 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
104 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
105 pbData[i+6], pbData[i+7]);
106 trace(szTemp);
108 for (j=0; i<dwLen; j++,i++) {
109 sprintf(szTemp+6*j, "0x%02x,\n", pbData[i]);
111 trace(szTemp);
115 static int init_base_environment(DWORD dwKeyFlags)
117 HCRYPTKEY hKey;
118 BOOL result;
120 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
122 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
124 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
125 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
127 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
129 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
130 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
131 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
132 CRYPT_NEWKEYSET);
133 ok(result, "%08x\n", GetLastError());
134 if (!result) return 0;
135 result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey);
136 ok(result, "%08x\n", GetLastError());
137 if (result) CryptDestroyKey(hKey);
138 result = CryptGenKey(hProv, AT_SIGNATURE, dwKeyFlags, &hKey);
139 ok(result, "%08x\n", GetLastError());
140 if (result) CryptDestroyKey(hKey);
142 return 1;
145 static void clean_up_base_environment(void)
147 BOOL result;
149 SetLastError(0xdeadbeef);
150 result = CryptReleaseContext(hProv, 1);
151 ok(!result || broken(result) /* Win98 */, "Expected failure\n");
152 ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
154 /* Just to prove that Win98 also released the CSP */
155 SetLastError(0xdeadbeef);
156 result = CryptReleaseContext(hProv, 0);
157 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
159 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
162 static int init_aes_environment(void)
164 HCRYPTKEY hKey;
165 BOOL result;
167 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
169 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
171 /* we are using NULL as provider name for RSA_AES provider as the provider
172 * names are different in Windows XP and Vista. Its different as to what
173 * its defined in the SDK on Windows XP.
174 * This provider is available on Windows XP, Windows 2003 and Vista. */
176 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
177 if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
179 win_skip("RSA_AES provider not supported\n");
180 return 0;
182 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
184 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
186 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
187 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
188 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
189 CRYPT_NEWKEYSET);
190 ok(result, "%08x\n", GetLastError());
191 if (!result) return 0;
192 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
193 ok(result, "%08x\n", GetLastError());
194 if (result) CryptDestroyKey(hKey);
195 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
196 ok(result, "%08x\n", GetLastError());
197 if (result) CryptDestroyKey(hKey);
199 return 1;
202 static void clean_up_aes_environment(void)
204 BOOL result;
206 result = CryptReleaseContext(hProv, 1);
207 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
209 CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
212 static void test_prov(void)
214 BOOL result;
215 DWORD dwLen, dwInc;
217 dwLen = (DWORD)sizeof(DWORD);
218 SetLastError(0xdeadbeef);
219 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
220 if (!result && GetLastError() == NTE_BAD_TYPE)
221 skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
222 else
223 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
225 dwLen = (DWORD)sizeof(DWORD);
226 SetLastError(0xdeadbeef);
227 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
228 if (!result && GetLastError() == NTE_BAD_TYPE)
229 skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
230 else
231 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
234 static void test_gen_random(void)
236 BOOL result;
237 BYTE rnd1[16], rnd2[16];
239 memset(rnd1, 0, sizeof(rnd1));
240 memset(rnd2, 0, sizeof(rnd2));
242 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
243 if (!result && GetLastError() == NTE_FAIL) {
244 /* rsaenh compiled without OpenSSL */
245 return;
248 ok(result, "%08x\n", GetLastError());
250 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
251 ok(result, "%08x\n", GetLastError());
253 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
256 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
258 HCRYPTHASH hHash;
259 BOOL result;
260 unsigned char pbData[2000];
261 int i;
263 *phKey = 0;
264 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
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 return FALSE;
271 ok(result, "%08x\n", GetLastError());
272 if (!result) return FALSE;
273 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
274 ok(result, "%08x\n", GetLastError());
275 if (!result) return FALSE;
276 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
277 ok(result, "%08x\n", GetLastError());
278 if (!result) return FALSE;
279 len = 2000;
280 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
281 ok(result, "%08x\n", GetLastError());
282 CryptDestroyHash(hHash);
283 return TRUE;
286 static void test_hashes(void)
288 static const unsigned char md2hash[16] = {
289 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
290 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
291 static const unsigned char md4hash[16] = {
292 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
293 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
294 static const unsigned char empty_md5hash[16] = {
295 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
296 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
297 static const unsigned char md5hash[16] = {
298 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
299 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
300 static const unsigned char sha1hash[20] = {
301 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
302 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
303 unsigned char pbData[2048];
304 BOOL result;
305 HCRYPTHASH hHash, hHashClone;
306 BYTE pbHashValue[36];
307 DWORD hashlen, len;
308 int i;
310 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
312 /* MD2 Hashing */
313 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
314 if (!result) {
315 /* rsaenh compiled without OpenSSL */
316 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
317 } else {
318 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
319 ok(result, "%08x\n", GetLastError());
321 len = sizeof(DWORD);
322 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
323 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
325 len = 16;
326 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
327 ok(result, "%08x\n", GetLastError());
329 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
331 result = CryptDestroyHash(hHash);
332 ok(result, "%08x\n", GetLastError());
335 /* MD4 Hashing */
336 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
337 ok(result, "%08x\n", GetLastError());
339 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
340 ok(result, "%08x\n", GetLastError());
342 len = sizeof(DWORD);
343 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
344 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
346 len = 16;
347 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
348 ok(result, "%08x\n", GetLastError());
350 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
352 result = CryptDestroyHash(hHash);
353 ok(result, "%08x\n", GetLastError());
355 /* MD5 Hashing */
356 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
357 ok(result, "%08x\n", GetLastError());
359 len = sizeof(DWORD);
360 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
361 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
363 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
364 ok(result, "%08x\n", GetLastError());
366 len = 16;
367 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
368 ok(result, "%08x\n", GetLastError());
370 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
372 result = CryptDestroyHash(hHash);
373 ok(result, "%08x\n", GetLastError());
375 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
376 ok(result, "%08x\n", GetLastError());
378 /* The hash is available even if CryptHashData hasn't been called */
379 len = 16;
380 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
381 ok(result, "%08x\n", GetLastError());
383 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
385 /* It's also stable: getting it twice results in the same value */
386 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
387 ok(result, "%08x\n", GetLastError());
389 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
391 /* Can't add data after the hash been retrieved */
392 SetLastError(0xdeadbeef);
393 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
394 ok(!result, "Expected failure\n");
395 ok(GetLastError() == NTE_BAD_HASH_STATE ||
396 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
397 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
399 /* You can still retrieve the hash, its value just hasn't changed */
400 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
401 ok(result, "%08x\n", GetLastError());
403 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
405 result = CryptDestroyHash(hHash);
406 ok(result, "%08x\n", GetLastError());
408 /* SHA1 Hashing */
409 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
410 ok(result, "%08x\n", GetLastError());
412 result = CryptHashData(hHash, pbData, 5, 0);
413 ok(result, "%08x\n", GetLastError());
415 if(pCryptDuplicateHash) {
416 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
417 ok(result, "%08x\n", GetLastError());
419 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
420 ok(result, "%08x\n", GetLastError());
422 len = sizeof(DWORD);
423 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
424 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
426 len = 20;
427 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
428 ok(result, "%08x\n", GetLastError());
430 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
432 result = CryptDestroyHash(hHashClone);
433 ok(result, "%08x\n", GetLastError());
436 result = CryptDestroyHash(hHash);
437 ok(result, "%08x\n", GetLastError());
440 static void test_block_cipher_modes(void)
442 static const BYTE plain[23] = {
443 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
444 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
445 static const BYTE ecb[24] = {
446 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
447 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
448 static const BYTE cbc[24] = {
449 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
450 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
451 static const BYTE cfb[24] = {
452 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
453 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
454 HCRYPTKEY hKey;
455 BOOL result;
456 BYTE abData[24];
457 DWORD dwMode, dwLen;
459 result = derive_key(CALG_RC2, &hKey, 40);
460 if (!result) return;
462 memcpy(abData, plain, sizeof(abData));
464 dwMode = CRYPT_MODE_ECB;
465 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
466 ok(result, "%08x\n", GetLastError());
468 dwLen = 23;
469 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
470 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
471 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
473 SetLastError(ERROR_SUCCESS);
474 dwLen = 23;
475 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
476 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
477 "%08x, dwLen: %d\n", GetLastError(), dwLen);
479 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
480 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
481 "%08x, dwLen: %d\n", GetLastError(), dwLen);
483 dwMode = CRYPT_MODE_CBC;
484 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
485 ok(result, "%08x\n", GetLastError());
487 dwLen = 23;
488 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
489 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
490 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
492 dwLen = 23;
493 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
494 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
495 "%08x, dwLen: %d\n", GetLastError(), dwLen);
497 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
498 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
499 "%08x, dwLen: %d\n", GetLastError(), dwLen);
501 dwMode = CRYPT_MODE_CFB;
502 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
503 ok(result, "%08x\n", GetLastError());
505 dwLen = 16;
506 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
507 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
509 dwLen = 7;
510 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
511 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
512 "%08x, dwLen: %d\n", GetLastError(), dwLen);
514 dwLen = 8;
515 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
516 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
518 dwLen = 16;
519 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
520 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
521 "%08x, dwLen: %d\n", GetLastError(), dwLen);
523 dwMode = CRYPT_MODE_OFB;
524 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
525 ok(result, "%08x\n", GetLastError());
527 dwLen = 23;
528 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
529 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
531 CryptDestroyKey(hKey);
534 static void test_3des112(void)
536 HCRYPTKEY hKey;
537 BOOL result;
538 DWORD dwLen;
539 unsigned char pbData[16];
540 int i;
542 result = derive_key(CALG_3DES_112, &hKey, 0);
543 if (!result) {
544 /* rsaenh compiled without OpenSSL */
545 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
546 return;
549 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
551 dwLen = 13;
552 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
553 ok(result, "%08x\n", GetLastError());
555 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
556 ok(result, "%08x\n", GetLastError());
558 for (i=0; i<4; i++)
560 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
562 dwLen = cTestData[i].enclen;
563 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
564 ok(result, "%08x\n", GetLastError());
565 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
567 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
568 ok(result, "%08x\n", GetLastError());
569 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
570 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
571 if((dwLen != cTestData[i].enclen) ||
572 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
574 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
575 printBytes("got",pbData,dwLen);
578 result = CryptDestroyKey(hKey);
579 ok(result, "%08x\n", GetLastError());
582 static void test_des(void)
584 HCRYPTKEY hKey;
585 BOOL result;
586 DWORD dwLen, dwMode;
587 unsigned char pbData[16];
588 int i;
590 result = derive_key(CALG_DES, &hKey, 56);
591 if (!result) {
592 /* rsaenh compiled without OpenSSL */
593 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
594 return;
597 dwMode = CRYPT_MODE_ECB;
598 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
599 ok(result, "%08x\n", GetLastError());
601 dwLen = sizeof(DWORD);
602 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
603 ok(result, "%08x\n", GetLastError());
605 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
607 dwLen = 13;
608 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
609 ok(result, "%08x\n", GetLastError());
611 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
612 ok(result, "%08x\n", GetLastError());
614 for (i=0; i<4; i++)
616 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
618 dwLen = cTestData[i].enclen;
619 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
620 ok(result, "%08x\n", GetLastError());
621 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
623 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
624 ok(result, "%08x\n", GetLastError());
625 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
626 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
627 if((dwLen != cTestData[i].enclen) ||
628 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
630 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
631 printBytes("got",pbData,dwLen);
635 result = CryptDestroyKey(hKey);
636 ok(result, "%08x\n", GetLastError());
639 static void test_3des(void)
641 HCRYPTKEY hKey;
642 BOOL result;
643 DWORD dwLen;
644 unsigned char pbData[16];
645 static const BYTE des3[16] = {
646 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
647 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
648 int i;
650 result = derive_key(CALG_3DES, &hKey, 0);
651 if (!result) return;
653 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
655 dwLen = 13;
656 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
657 ok(result, "%08x\n", GetLastError());
659 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
661 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
662 ok(result, "%08x\n", GetLastError());
664 for (i=0; i<4; i++)
666 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
668 dwLen = cTestData[i].enclen;
669 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
670 ok(result, "%08x\n", GetLastError());
671 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
673 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
674 ok(result, "%08x\n", GetLastError());
675 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
676 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
677 if((dwLen != cTestData[i].enclen) ||
678 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
680 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
681 printBytes("got",pbData,dwLen);
684 result = CryptDestroyKey(hKey);
685 ok(result, "%08x\n", GetLastError());
688 static void test_aes(int keylen)
690 HCRYPTKEY hKey;
691 BOOL result;
692 DWORD dwLen;
693 unsigned char pbData[16];
694 int i;
696 switch (keylen)
698 case 256:
699 result = derive_key(CALG_AES_256, &hKey, 0);
700 break;
701 case 192:
702 result = derive_key(CALG_AES_192, &hKey, 0);
703 break;
704 default:
705 case 128:
706 result = derive_key(CALG_AES_128, &hKey, 0);
707 break;
709 if (!result) return;
711 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
713 dwLen = 13;
714 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
715 ok(result, "%08x\n", GetLastError());
717 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
718 ok(result, "%08x\n", GetLastError());
720 for (i=0; i<4; i++)
722 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
724 dwLen = cTestData[i].enclen;
725 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
726 ok(result, "%08x\n", GetLastError());
727 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
729 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
730 ok(result, "%08x\n", GetLastError());
731 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
732 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
733 if((dwLen != cTestData[i].enclen) ||
734 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
736 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
737 printBytes("got",pbData,dwLen);
740 result = CryptDestroyKey(hKey);
741 ok(result, "%08x\n", GetLastError());
744 static void test_rc2(void)
746 static const BYTE rc2_40_encrypted[16] = {
747 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
748 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
749 static const BYTE rc2_128_encrypted[] = {
750 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
751 0xb6,0x66 };
752 HCRYPTHASH hHash;
753 HCRYPTKEY hKey;
754 BOOL result;
755 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
756 BYTE *pbTemp;
757 unsigned char pbData[2000], pbHashValue[16];
758 int i;
760 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
762 /* MD2 Hashing */
763 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
764 if (!result) {
765 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
766 } else {
767 CRYPT_INTEGER_BLOB salt;
769 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
770 ok(result, "%08x\n", GetLastError());
772 dwLen = 16;
773 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
774 ok(result, "%08x\n", GetLastError());
776 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
777 ok(result, "%08x\n", GetLastError());
779 dwLen = sizeof(DWORD);
780 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
781 ok(result, "%08x\n", GetLastError());
783 dwMode = CRYPT_MODE_CBC;
784 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
785 ok(result, "%08x\n", GetLastError());
787 dwLen = sizeof(DWORD);
788 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
789 ok(result, "%08x\n", GetLastError());
791 dwModeBits = 0xdeadbeef;
792 dwLen = sizeof(DWORD);
793 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
794 ok(result, "%08x\n", GetLastError());
795 ok(dwModeBits ==
796 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
797 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
798 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
799 " got %08x\n", dwModeBits);
801 dwLen = sizeof(DWORD);
802 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
803 ok(result, "%08x\n", GetLastError());
805 dwLen = sizeof(DWORD);
806 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
807 ok(result, "%08x\n", GetLastError());
809 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
810 ok(result, "%08x\n", GetLastError());
811 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
812 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
813 HeapFree(GetProcessHeap(), 0, pbTemp);
815 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
816 ok(result, "%08x\n", GetLastError());
817 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
818 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
819 HeapFree(GetProcessHeap(), 0, pbTemp);
821 dwLen = sizeof(DWORD);
822 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
824 result = CryptDestroyHash(hHash);
825 ok(result, "%08x\n", GetLastError());
827 dwDataLen = 13;
828 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
829 ok(result, "%08x\n", GetLastError());
831 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
833 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
834 ok(result, "%08x\n", GetLastError());
835 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
836 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
837 HeapFree(GetProcessHeap(), 0, pbTemp);
839 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
840 ok(result, "%08x\n", GetLastError());
842 /* What sizes salt can I set? */
843 salt.pbData = pbData;
844 for (i=0; i<24; i++)
846 salt.cbData = i;
847 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
848 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
850 salt.cbData = 25;
851 SetLastError(0xdeadbeef);
852 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
853 ok(!result ||
854 broken(result), /* Win9x, WinMe, NT4, W2K */
855 "%08x\n", GetLastError());
857 result = CryptDestroyKey(hKey);
858 ok(result, "%08x\n", GetLastError());
861 /* Again, but test setting the effective key len */
862 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
864 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
865 if (!result) {
866 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
867 } else {
868 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
869 ok(result, "%08x\n", GetLastError());
871 dwLen = 16;
872 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
873 ok(result, "%08x\n", GetLastError());
875 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
876 ok(result, "%08x\n", GetLastError());
878 SetLastError(0xdeadbeef);
879 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
880 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
881 dwKeyLen = 0;
882 SetLastError(0xdeadbeef);
883 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
884 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
885 dwKeyLen = 1025;
886 SetLastError(0xdeadbeef);
887 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
889 dwLen = sizeof(dwKeyLen);
890 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
891 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
892 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
893 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
895 dwKeyLen = 128;
896 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
897 ok(result, "%d\n", GetLastError());
899 dwLen = sizeof(dwKeyLen);
900 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
901 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
902 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
903 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
905 result = CryptDestroyHash(hHash);
906 ok(result, "%08x\n", GetLastError());
908 dwDataLen = 13;
909 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
910 ok(result, "%08x\n", GetLastError());
912 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
913 "RC2 encryption failed!\n");
915 /* Oddly enough this succeeds, though it should have no effect */
916 dwKeyLen = 40;
917 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
918 ok(result, "%d\n", GetLastError());
920 result = CryptDestroyKey(hKey);
921 ok(result, "%08x\n", GetLastError());
925 static void test_rc4(void)
927 static const BYTE rc4[16] = {
928 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
929 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
930 BOOL result;
931 HCRYPTHASH hHash;
932 HCRYPTKEY hKey;
933 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
934 unsigned char pbData[2000], *pbTemp;
935 unsigned char pszBuffer[256];
936 int i;
938 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
940 /* MD2 Hashing */
941 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
942 if (!result) {
943 /* rsaenh compiled without OpenSSL */
944 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
945 } else {
946 CRYPT_INTEGER_BLOB salt;
948 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
949 ok(result, "%08x\n", GetLastError());
951 dwLen = 16;
952 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
953 ok(result, "%08x\n", GetLastError());
955 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
956 ok(result, "%08x\n", GetLastError());
958 dwLen = sizeof(DWORD);
959 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
960 ok(result, "%08x\n", GetLastError());
962 dwLen = sizeof(DWORD);
963 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
964 ok(result, "%08x\n", GetLastError());
966 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
967 ok(result, "%08x\n", GetLastError());
968 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
969 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
970 HeapFree(GetProcessHeap(), 0, pbTemp);
972 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
973 ok(result, "%08x\n", GetLastError());
974 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
975 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
976 HeapFree(GetProcessHeap(), 0, pbTemp);
978 dwLen = sizeof(DWORD);
979 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
981 result = CryptDestroyHash(hHash);
982 ok(result, "%08x\n", GetLastError());
984 dwDataLen = 16;
985 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
986 ok(result, "%08x\n", GetLastError());
987 dwDataLen = 16;
988 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
989 ok(result, "%08x\n", GetLastError());
991 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
993 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
994 ok(result, "%08x\n", GetLastError());
996 /* What sizes salt can I set? */
997 salt.pbData = pbData;
998 for (i=0; i<24; i++)
1000 salt.cbData = i;
1001 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1002 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1004 salt.cbData = 25;
1005 SetLastError(0xdeadbeef);
1006 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1007 ok(!result ||
1008 broken(result), /* Win9x, WinMe, NT4, W2K */
1009 "%08x\n", GetLastError());
1011 result = CryptDestroyKey(hKey);
1012 ok(result, "%08x\n", GetLastError());
1016 static void test_hmac(void) {
1017 HCRYPTKEY hKey;
1018 HCRYPTHASH hHash;
1019 BOOL result;
1020 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1021 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1022 DWORD dwLen;
1023 BYTE abData[256];
1024 static const BYTE hmac[16] = {
1025 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1026 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1027 int i;
1029 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1031 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1033 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1034 ok(result, "%08x\n", GetLastError());
1035 if (!result) return;
1037 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1038 ok(result, "%08x\n", GetLastError());
1040 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1041 ok(result, "%08x\n", GetLastError());
1043 dwLen = sizeof(abData)/sizeof(BYTE);
1044 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1045 ok(result, "%08x\n", GetLastError());
1047 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1049 result = CryptDestroyHash(hHash);
1050 ok(result, "%08x\n", GetLastError());
1052 result = CryptDestroyKey(hKey);
1053 ok(result, "%08x\n", GetLastError());
1055 /* Provoke errors */
1056 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1057 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1060 static void test_mac(void) {
1061 HCRYPTKEY hKey;
1062 HCRYPTHASH hHash;
1063 BOOL result;
1064 DWORD dwLen;
1065 BYTE abData[256], abEnc[264];
1066 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1067 int i;
1069 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1070 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1072 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1074 dwLen = 256;
1075 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1076 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1078 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1079 ok(result, "%08x\n", GetLastError());
1080 if (!result) return;
1082 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1083 ok(result, "%08x\n", GetLastError());
1085 dwLen = sizeof(abData)/sizeof(BYTE);
1086 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1087 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1089 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1091 result = CryptDestroyHash(hHash);
1092 ok(result, "%08x\n", GetLastError());
1094 result = CryptDestroyKey(hKey);
1095 ok(result, "%08x\n", GetLastError());
1097 /* Provoke errors */
1098 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1100 SetLastError(0xdeadbeef);
1101 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1102 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1103 broken(result), /* Win9x, WinMe, NT4, W2K */
1104 "%08x\n", GetLastError());
1106 result = CryptDestroyKey(hKey);
1107 ok(result, "%08x\n", GetLastError());
1110 static BYTE abPlainPrivateKey[596] = {
1111 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1112 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1113 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1114 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1115 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1116 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1117 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1118 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1119 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1120 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1121 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1122 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1123 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1124 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1125 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1126 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1127 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1128 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1129 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1130 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1131 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1132 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1133 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1134 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1135 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1136 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1137 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1138 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1139 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1140 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1141 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1142 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1143 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1144 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1145 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1146 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1147 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1148 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1149 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1150 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1151 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1152 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1153 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1154 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1155 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1156 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1157 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1158 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1159 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1160 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1161 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1162 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1163 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1164 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1165 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1166 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1167 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1168 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1169 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1170 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1171 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1172 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1173 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1174 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1175 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1176 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1177 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1178 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1179 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1180 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1181 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1182 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1183 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1184 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1185 0xf2, 0x5d, 0x58, 0x07
1188 static void test_import_private(void)
1190 DWORD dwLen, dwVal;
1191 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1192 BOOL result;
1193 static BYTE abSessionKey[148] = {
1194 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1195 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1196 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1197 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1198 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1199 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1200 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1201 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1202 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1203 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1204 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1205 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1206 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1207 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1208 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1209 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1210 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1211 0x04, 0x8c, 0x49, 0x92
1213 static BYTE abEncryptedMessage[12] = {
1214 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1215 0x1c, 0xfd, 0xde, 0x71
1218 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1219 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1220 if (!result) {
1221 /* rsaenh compiled without OpenSSL */
1222 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1223 return;
1226 dwLen = (DWORD)sizeof(abSessionKey);
1227 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1228 ok(result, "%08x\n", GetLastError());
1229 if (!result) return;
1231 dwVal = 0xdeadbeef;
1232 dwLen = sizeof(DWORD);
1233 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1234 ok(result, "%08x\n", GetLastError());
1235 ok(dwVal ==
1236 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1237 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1238 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1239 " got %08x\n", dwVal);
1241 dwLen = (DWORD)sizeof(abEncryptedMessage);
1242 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1243 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1244 "%08x, len: %d\n", GetLastError(), dwLen);
1245 CryptDestroyKey(hSessionKey);
1247 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1249 dwLen = (DWORD)sizeof(abSessionKey);
1250 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1251 ok(result, "%08x\n", GetLastError());
1252 CryptDestroyKey(hSessionKey);
1253 if (!result) return;
1255 dwLen = (DWORD)sizeof(abSessionKey);
1256 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1257 ok(result, "%08x\n", GetLastError());
1258 if (!result) return;
1260 CryptDestroyKey(hSessionKey);
1261 CryptDestroyKey(hKeyExchangeKey);
1264 static void test_verify_signature(void) {
1265 HCRYPTHASH hHash;
1266 HCRYPTKEY hPubSignKey;
1267 BYTE abData[] = "Wine rocks!";
1268 BOOL result;
1269 BYTE abPubKey[148] = {
1270 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1271 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1272 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1273 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1274 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1275 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1276 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1277 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1278 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1279 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1280 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1281 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1282 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1283 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1284 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1285 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1286 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1287 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1288 0xe1, 0x21, 0x50, 0xac
1290 /* md2 with hash oid */
1291 BYTE abSignatureMD2[128] = {
1292 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1293 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1294 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1295 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1296 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1297 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1298 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1299 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1300 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1301 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1302 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1303 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1304 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1305 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1306 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1307 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1309 /* md2 without hash oid */
1310 BYTE abSignatureMD2NoOID[128] = {
1311 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1312 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1313 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1314 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1315 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1316 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1317 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1318 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1319 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1320 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1321 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1322 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1323 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1324 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1325 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1326 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1328 /* md4 with hash oid */
1329 BYTE abSignatureMD4[128] = {
1330 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1331 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1332 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1333 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1334 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1335 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1336 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1337 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1338 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1339 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1340 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1341 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1342 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1343 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1344 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1345 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1347 /* md4 without hash oid */
1348 BYTE abSignatureMD4NoOID[128] = {
1349 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1350 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1351 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1352 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1353 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1354 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1355 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1356 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1357 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1358 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1359 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1360 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1361 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1362 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1363 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1364 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1366 /* md5 with hash oid */
1367 BYTE abSignatureMD5[128] = {
1368 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1369 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1370 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1371 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1372 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1373 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1374 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1375 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1376 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1377 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1378 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1379 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1380 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1381 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1382 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1383 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1385 /* md5 without hash oid */
1386 BYTE abSignatureMD5NoOID[128] = {
1387 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1388 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1389 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1390 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1391 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1392 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1393 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1394 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1395 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1396 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1397 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1398 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1399 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1400 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1401 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1402 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1404 /* sha with hash oid */
1405 BYTE abSignatureSHA[128] = {
1406 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1407 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1408 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1409 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1410 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1411 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1412 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1413 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1414 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1415 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1416 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1417 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1418 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1419 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1420 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1421 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1423 /* sha without hash oid */
1424 BYTE abSignatureSHANoOID[128] = {
1425 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1426 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1427 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1428 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1429 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1430 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1431 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1432 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1433 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1434 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1435 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1436 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1437 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1438 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1439 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1440 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1443 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1444 ok(result, "%08x\n", GetLastError());
1445 if (!result) return;
1447 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1448 ok(result, "%08x\n", GetLastError());
1449 if (!result) return;
1451 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1452 ok(result, "%08x\n", GetLastError());
1453 if (!result) return;
1455 /*check that a NULL pointer signature is correctly handled*/
1456 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1457 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1458 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1459 if (result) return;
1461 /* check that we get a bad signature error when the signature is too short*/
1462 SetLastError(0xdeadbeef);
1463 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1464 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1465 broken(result), /* Win9x, WinMe, NT4 */
1466 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1468 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1469 ok(result, "%08x\n", GetLastError());
1470 if (!result) return;
1472 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1473 ok(result, "%08x\n", GetLastError());
1474 if (!result) return;
1476 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1477 * the OID at all. */
1478 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1479 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1480 if (result) return;*/
1482 CryptDestroyHash(hHash);
1484 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1485 ok(result, "%08x\n", GetLastError());
1486 if (!result) return;
1488 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1489 ok(result, "%08x\n", GetLastError());
1490 if (!result) return;
1492 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1493 ok(result, "%08x\n", GetLastError());
1494 if (!result) return;
1496 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1497 ok(result, "%08x\n", GetLastError());
1498 if (!result) return;
1500 CryptDestroyHash(hHash);
1502 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1503 ok(result, "%08x\n", GetLastError());
1504 if (!result) return;
1506 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1507 ok(result, "%08x\n", GetLastError());
1508 if (!result) return;
1510 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1511 ok(result, "%08x\n", GetLastError());
1512 if (!result) return;
1514 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1515 ok(result, "%08x\n", GetLastError());
1516 if (!result) return;
1518 CryptDestroyHash(hHash);
1520 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1521 ok(result, "%08x\n", GetLastError());
1522 if (!result) return;
1524 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1525 ok(result, "%08x\n", GetLastError());
1526 if (!result) return;
1528 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1529 ok(result, "%08x\n", GetLastError());
1530 if (!result) return;
1532 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1533 ok(result, "%08x\n", GetLastError());
1534 if (!result) return;
1536 CryptDestroyHash(hHash);
1537 CryptDestroyKey(hPubSignKey);
1540 static void test_rsa_encrypt(void)
1542 HCRYPTKEY hRSAKey;
1543 BYTE abData[2048] = "Wine rocks!";
1544 BOOL result;
1545 DWORD dwVal, dwLen;
1547 /* It is allowed to use the key exchange key for encryption/decryption */
1548 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1549 ok (result, "%08x\n", GetLastError());
1550 if (!result) return;
1552 dwLen = 12;
1553 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1554 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1555 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1556 dwLen = 12;
1557 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1558 ok (result, "%08x\n", GetLastError());
1559 if (!result) return;
1561 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1562 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1564 dwVal = 0xdeadbeef;
1565 dwLen = sizeof(DWORD);
1566 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1567 ok(result, "%08x\n", GetLastError());
1568 ok(dwVal ==
1569 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1570 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1571 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1572 " got %08x\n", dwVal);
1574 /* The key exchange key's public key may be exported.. */
1575 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1576 ok(result, "%08x\n", GetLastError());
1577 /* but its private key may not be. */
1578 SetLastError(0xdeadbeef);
1579 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1580 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1581 broken(result), /* Win9x/NT4 */
1582 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1583 /* Setting the permissions of the key exchange key isn't allowed, either. */
1584 dwVal |= CRYPT_EXPORT;
1585 SetLastError(0xdeadbeef);
1586 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1587 ok(!result &&
1588 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1589 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1591 CryptDestroyKey(hRSAKey);
1593 /* It is not allowed to use the signature key for encryption/decryption */
1594 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1595 ok (result, "%08x\n", GetLastError());
1596 if (!result) return;
1598 dwVal = 0xdeadbeef;
1599 dwLen = sizeof(DWORD);
1600 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1601 ok(result, "%08x\n", GetLastError());
1602 ok(dwVal ==
1603 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1604 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1605 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1606 " got %08x\n", dwVal);
1608 /* The signature key's public key may also be exported.. */
1609 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1610 ok(result, "%08x\n", GetLastError());
1611 /* but its private key may not be. */
1612 SetLastError(0xdeadbeef);
1613 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1614 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1615 broken(result), /* Win9x/NT4 */
1616 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1617 /* Setting the permissions of the signature key isn't allowed, either. */
1618 dwVal |= CRYPT_EXPORT;
1619 SetLastError(0xdeadbeef);
1620 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1621 ok(!result &&
1622 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1623 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1625 dwLen = 12;
1626 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1627 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1629 CryptDestroyKey(hRSAKey);
1632 static void test_import_export(void)
1634 DWORD dwLen, dwDataLen, dwVal;
1635 HCRYPTKEY hPublicKey, hPrivKey;
1636 BOOL result;
1637 ALG_ID algID;
1638 BYTE emptyKey[2048], *exported_key;
1639 static BYTE abPlainPublicKey[84] = {
1640 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1641 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1642 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1643 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1644 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1645 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1646 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1647 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1648 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1649 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1650 0x11, 0x11, 0x11, 0x11
1652 static BYTE priv_key_with_high_bit[] = {
1653 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1654 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1655 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1656 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1657 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1658 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1659 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1660 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1661 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1662 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1663 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1664 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1665 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1666 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1667 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1668 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1669 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1670 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1671 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1672 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1673 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1674 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1675 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1676 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1677 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1678 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1679 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1680 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1681 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1682 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1683 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1684 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1685 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1686 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1687 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1688 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1689 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1690 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1691 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1692 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1693 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1694 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1695 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1696 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1697 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1698 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1699 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1700 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1701 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1702 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1703 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1704 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1705 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1706 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1707 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1708 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1709 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1710 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1711 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1712 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1713 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1714 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1715 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1716 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1717 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1718 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1719 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1720 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1721 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1722 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1723 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1724 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1725 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1726 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1727 0xb6, 0x5f, 0x01, 0x5e
1729 static const BYTE expected_exported_priv_key[] = {
1730 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1731 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1732 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1733 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1734 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1735 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1736 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1737 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1738 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1739 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1740 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1741 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1742 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1743 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1744 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1745 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1746 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1747 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1748 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1749 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1750 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1751 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1752 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1753 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1754 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1755 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1756 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1757 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1758 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1759 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1760 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1761 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1762 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1763 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1764 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1765 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1766 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1767 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1768 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1769 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1770 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1771 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1772 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1773 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1774 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1775 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1776 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1777 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1778 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1779 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1780 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1781 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1782 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1783 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1784 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1785 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1786 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1787 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1788 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1789 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1790 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1791 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1792 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1793 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1794 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1795 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1796 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1797 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1798 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1799 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1800 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1801 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1802 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1803 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1804 0xb6, 0x5f, 0x01, 0x5e
1807 dwLen=84;
1808 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1809 ok(result, "failed to import the public key\n");
1811 dwDataLen=sizeof(algID);
1812 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1813 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1814 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1816 dwVal = 0xdeadbeef;
1817 dwDataLen = sizeof(DWORD);
1818 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
1819 ok(result, "%08x\n", GetLastError());
1820 ok(dwVal ==
1821 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1822 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1823 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1824 " got %08x\n", dwVal);
1825 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1826 ok(result, "failed to export the fresh imported public key\n");
1827 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1828 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1830 CryptDestroyKey(hPublicKey);
1832 result = CryptImportKey(hProv, priv_key_with_high_bit,
1833 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
1834 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1836 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
1837 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
1838 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
1839 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
1840 &dwDataLen);
1841 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
1843 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
1844 dwDataLen);
1845 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
1846 "unexpected value\n");
1848 HeapFree(GetProcessHeap(), 0, exported_key);
1850 CryptDestroyKey(hPrivKey);
1853 static void test_schannel_provider(void)
1855 HCRYPTPROV hProv;
1856 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1857 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1858 BOOL result;
1859 DWORD dwLen;
1860 SCHANNEL_ALG saSChannelAlg;
1861 CRYPT_DATA_BLOB data_blob;
1862 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1863 BYTE abTLS1Master[140] = {
1864 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1865 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1866 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1867 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1868 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1869 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1870 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1871 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1872 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1873 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1874 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1875 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1876 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1877 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1878 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1879 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1880 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1881 0xd3, 0x1e, 0x82, 0xb3
1883 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1884 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1885 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1886 BYTE abClientFinished[16] = "client finished";
1887 BYTE abData[16] = "Wine rocks!";
1888 BYTE abMD5Hash[16];
1889 static const BYTE abEncryptedData[16] = {
1890 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1891 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1893 static const BYTE abPRF[16] = {
1894 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1895 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1897 static const BYTE abMD5[16] = {
1898 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1899 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1902 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1903 if (!result)
1905 win_skip("no PROV_RSA_SCHANNEL support\n");
1906 return;
1908 ok (result, "%08x\n", GetLastError());
1909 if (result)
1910 CryptReleaseContext(hProv, 0);
1912 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1913 ok (result, "%08x\n", GetLastError());
1914 if (!result) return;
1916 /* To get deterministic results, we import the TLS1 master secret (which
1917 * is typically generated from a random generator). Therefore, we need
1918 * an RSA key. */
1919 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1920 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1921 ok (result, "%08x\n", GetLastError());
1922 if (!result) return;
1924 dwLen = (DWORD)sizeof(abTLS1Master);
1925 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1926 ok (result, "%08x\n", GetLastError());
1927 if (!result) return;
1929 /* Setting the TLS1 client and server random parameters, as well as the
1930 * MAC and encryption algorithm parameters. */
1931 data_blob.cbData = 33;
1932 data_blob.pbData = abClientSecret;
1933 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1934 ok (result, "%08x\n", GetLastError());
1935 if (!result) return;
1937 data_blob.cbData = 33;
1938 data_blob.pbData = abServerSecret;
1939 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1940 ok (result, "%08x\n", GetLastError());
1941 if (!result) return;
1943 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1944 saSChannelAlg.Algid = CALG_DES;
1945 saSChannelAlg.cBits = 64;
1946 saSChannelAlg.dwFlags = 0;
1947 saSChannelAlg.dwReserved = 0;
1948 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1949 ok (result, "%08x\n", GetLastError());
1950 if (!result) return;
1952 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1953 saSChannelAlg.Algid = CALG_MD5;
1954 saSChannelAlg.cBits = 128;
1955 saSChannelAlg.dwFlags = 0;
1956 saSChannelAlg.dwReserved = 0;
1957 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1958 ok (result, "%08x\n", GetLastError());
1959 if (!result) return;
1961 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1962 * (Keys can only be derived from hashes, not from other keys.) */
1963 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1964 ok (result, "%08x\n", GetLastError());
1965 if (!result) return;
1967 /* Deriving the server write encryption key from the master hash */
1968 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1969 ok (result, "%08x\n", GetLastError());
1970 if (!result) return;
1972 /* Encrypting some data with the server write encryption key and checking the result. */
1973 dwLen = 12;
1974 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1975 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1977 /* Second test case: Test the TLS1 pseudo random number function. */
1978 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1979 ok (result, "%08x\n", GetLastError());
1980 if (!result) return;
1982 /* Set the label and seed parameters for the random number function */
1983 data_blob.cbData = 36;
1984 data_blob.pbData = abHashedHandshakes;
1985 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1986 ok (result, "%08x\n", GetLastError());
1987 if (!result) return;
1989 data_blob.cbData = 15;
1990 data_blob.pbData = abClientFinished;
1991 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1992 ok (result, "%08x\n", GetLastError());
1993 if (!result) return;
1995 /* Generate some pseudo random bytes and check if they are correct. */
1996 dwLen = (DWORD)sizeof(abData);
1997 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1998 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1999 "%08x\n", GetLastError());
2001 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2002 * Hash some data with the HMAC. Compare results. */
2003 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2004 ok (result, "%08x\n", GetLastError());
2005 if (!result) return;
2007 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2008 ok (result, "%08x\n", GetLastError());
2009 if (!result) return;
2011 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2012 ok (result, "%08x\n", GetLastError());
2013 if (!result) return;
2015 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2016 ok (result, "%08x\n", GetLastError());
2017 if (!result) return;
2019 dwLen = (DWORD)sizeof(abMD5Hash);
2020 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2021 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2023 CryptDestroyHash(hHMAC);
2024 CryptDestroyHash(hTLS1PRF);
2025 CryptDestroyHash(hMasterHash);
2026 CryptDestroyKey(hServerWriteMACKey);
2027 CryptDestroyKey(hServerWriteKey);
2028 CryptDestroyKey(hRSAKey);
2029 CryptDestroyKey(hMasterSecret);
2030 CryptReleaseContext(hProv, 0);
2031 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2034 /* Test that a key can be used to encrypt data and exported, and that, when
2035 * the exported key is imported again, can be used to decrypt the original
2036 * data again.
2038 static void test_rsa_round_trip(void)
2040 static const char test_string[] = "Well this is a fine how-do-you-do.";
2041 HCRYPTPROV prov;
2042 HCRYPTKEY signKey, keyExchangeKey;
2043 BOOL result;
2044 BYTE data[256], *exportedKey;
2045 DWORD dataLen, keyLen;
2047 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2048 CRYPT_DELETEKEYSET);
2050 /* Generate a new key... */
2051 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2052 CRYPT_NEWKEYSET);
2053 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2054 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2055 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2056 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2057 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2058 /* encrypt some data with it... */
2059 memcpy(data, test_string, strlen(test_string) + 1);
2060 dataLen = strlen(test_string) + 1;
2061 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2062 sizeof(data));
2063 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2064 "CryptEncrypt failed: %08x\n", GetLastError());
2065 /* export the key... */
2066 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2067 &keyLen);
2068 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2069 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2070 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2071 &keyLen);
2072 /* destroy the key... */
2073 CryptDestroyKey(keyExchangeKey);
2074 CryptDestroyKey(signKey);
2075 /* import the key again... */
2076 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2077 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2078 HeapFree(GetProcessHeap(), 0, exportedKey);
2079 /* and decrypt the data encrypted with the original key with the imported
2080 * key.
2082 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2083 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2084 "CryptDecrypt failed: %08x\n", GetLastError());
2085 if (result)
2087 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2088 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value");
2090 CryptReleaseContext(prov, 0);
2092 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2093 CRYPT_DELETEKEYSET);
2096 static void test_enum_container(void)
2098 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2099 DWORD dwBufferLen;
2100 BOOL result, fFound = FALSE;
2102 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2103 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2104 SetLastError(0xdeadbeef);
2105 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2106 ok (result, "%08x\n", GetLastError());
2107 ok (dwBufferLen == MAX_PATH + 1 ||
2108 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2109 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2111 /* If the result fits into abContainerName dwBufferLen is left untouched */
2112 dwBufferLen = (DWORD)sizeof(abContainerName);
2113 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2114 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2116 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2117 do {
2118 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2119 dwBufferLen = (DWORD)sizeof(abContainerName);
2120 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2122 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2125 static BYTE signBlob[] = {
2126 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2127 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2128 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2129 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2130 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2131 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2132 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2133 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2134 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2135 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2136 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2137 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2138 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2139 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2140 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2141 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2142 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2143 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2144 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2145 0xb6,0x85,0x86,0x07 };
2147 static void test_null_provider(void)
2149 HCRYPTPROV prov;
2150 HCRYPTKEY key;
2151 BOOL result;
2152 DWORD keySpec, dataLen,dwParam;
2153 char szName[MAX_PATH];
2155 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2156 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2157 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2158 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2159 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2160 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2161 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2162 CRYPT_DELETEKEYSET);
2163 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2164 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2165 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2166 CRYPT_DELETEKEYSET);
2167 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2168 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2169 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2170 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2171 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2173 /* Delete the default container. */
2174 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2175 /* Once you've deleted the default container you can't open it as if it
2176 * already exists.
2178 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2179 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2180 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2181 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2182 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2183 CRYPT_VERIFYCONTEXT);
2184 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2185 if (!result) return;
2186 dataLen = sizeof(keySpec);
2187 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2188 if (result)
2189 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2190 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2191 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2192 * supported, you can't get the keys from this container.
2194 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2195 ok(!result && GetLastError() == NTE_NO_KEY,
2196 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2197 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2198 ok(!result && GetLastError() == NTE_NO_KEY,
2199 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2200 result = CryptReleaseContext(prov, 0);
2201 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2202 /* You can create a new default container. */
2203 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2204 CRYPT_NEWKEYSET);
2205 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2206 /* But you still can't get the keys (until one's been generated.) */
2207 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2208 ok(!result && GetLastError() == NTE_NO_KEY,
2209 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2210 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2211 ok(!result && GetLastError() == NTE_NO_KEY,
2212 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2213 CryptReleaseContext(prov, 0);
2214 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2216 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2217 CRYPT_DELETEKEYSET);
2218 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2219 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2220 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2221 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2222 CRYPT_VERIFYCONTEXT);
2223 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2224 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2225 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2226 CRYPT_NEWKEYSET);
2227 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2228 if (!result) return;
2229 /* Test provider parameters getter */
2230 dataLen = sizeof(dwParam);
2231 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2232 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2233 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2234 dataLen = sizeof(dwParam);
2235 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2236 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2237 "Expected 0, got 0x%08X\n",dwParam);
2238 dataLen = sizeof(dwParam);
2239 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2240 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2241 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2242 dataLen = sizeof(keySpec);
2243 SetLastError(0xdeadbeef);
2244 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2245 if (!result && GetLastError() == NTE_BAD_TYPE)
2246 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2247 else
2248 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2249 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2250 /* PP_CONTAINER parameter */
2251 dataLen = sizeof(szName);
2252 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2253 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2254 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2255 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2256 /* PP_UNIQUE_CONTAINER parameter */
2257 dataLen = sizeof(szName);
2258 SetLastError(0xdeadbeef);
2259 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2260 if (!result && GetLastError() == NTE_BAD_TYPE)
2262 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2264 else
2266 char container[MAX_PATH];
2268 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2269 uniquecontainer(container);
2270 todo_wine
2272 ok(dataLen == strlen(container)+1 ||
2273 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2274 "Expected a param length of 70, got %d\n", dataLen);
2275 ok(!strcmp(container, szName) ||
2276 broken(!strcmp(szName, szContainer)) /* WinME */,
2277 "Wrong container name : %s\n", szName);
2280 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2281 ok(!result && GetLastError() == NTE_NO_KEY,
2282 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2283 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2284 ok(!result && GetLastError() == NTE_NO_KEY,
2285 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2287 /* Importing a key exchange blob.. */
2288 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2289 0, 0, &key);
2290 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2291 CryptDestroyKey(key);
2292 /* allows access to the key exchange key.. */
2293 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2294 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2295 CryptDestroyKey(key);
2296 /* but not to the private key. */
2297 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2298 ok(!result && GetLastError() == NTE_NO_KEY,
2299 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2300 CryptReleaseContext(prov, 0);
2301 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2302 CRYPT_DELETEKEYSET);
2304 /* Whereas importing a sign blob.. */
2305 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2306 CRYPT_NEWKEYSET);
2307 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2308 if (!result) return;
2309 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2310 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2311 CryptDestroyKey(key);
2312 /* doesn't allow access to the key exchange key.. */
2313 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2314 ok(!result && GetLastError() == NTE_NO_KEY,
2315 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2316 /* but does to the private key. */
2317 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2318 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2319 CryptDestroyKey(key);
2320 CryptReleaseContext(prov, 0);
2322 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2323 CRYPT_DELETEKEYSET);
2325 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2326 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2327 CRYPT_NEWKEYSET);
2328 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2329 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2330 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2331 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2332 ok(!result, "expected CryptGetUserKey to fail\n");
2333 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2334 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2335 CryptDestroyKey(key);
2336 CryptReleaseContext(prov, 0);
2338 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2339 CRYPT_DELETEKEYSET);
2341 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2342 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2343 CRYPT_NEWKEYSET);
2344 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2345 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2346 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2347 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2348 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2349 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2350 ok(!result, "expected CryptGetUserKey to fail\n");
2351 CryptDestroyKey(key);
2352 CryptReleaseContext(prov, 0);
2354 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2355 CRYPT_DELETEKEYSET);
2357 /* test for the bug in accessing the user key in a container
2359 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2360 CRYPT_NEWKEYSET);
2361 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2362 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2363 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2364 CryptDestroyKey(key);
2365 CryptReleaseContext(prov,0);
2366 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2367 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2368 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2369 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2370 CryptDestroyKey(key);
2371 CryptReleaseContext(prov, 0);
2373 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2374 CRYPT_DELETEKEYSET);
2376 /* test the machine key set */
2377 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2378 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2379 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2380 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2381 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2382 CryptReleaseContext(prov, 0);
2383 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2384 CRYPT_MACHINE_KEYSET);
2385 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2386 CryptReleaseContext(prov,0);
2387 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2388 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2389 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2390 GetLastError());
2391 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2392 CRYPT_MACHINE_KEYSET);
2393 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2394 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2398 static void test_key_permissions(void)
2400 HCRYPTKEY hKey1, hKey2;
2401 DWORD dwVal, dwLen;
2402 BOOL result;
2404 /* Create keys that are exportable */
2405 if (!init_base_environment(CRYPT_EXPORTABLE))
2406 return;
2408 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2409 ok (result, "%08x\n", GetLastError());
2410 if (!result) return;
2412 dwVal = 0xdeadbeef;
2413 dwLen = sizeof(DWORD);
2414 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2415 ok(result, "%08x\n", GetLastError());
2416 ok(dwVal ==
2417 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2418 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2419 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2420 " got %08x\n", dwVal);
2422 /* The key exchange key's public key may be exported.. */
2423 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2424 ok(result, "%08x\n", GetLastError());
2425 /* and its private key may be too. */
2426 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2427 ok(result, "%08x\n", GetLastError());
2428 /* Turning off the key's export permissions is "allowed".. */
2429 dwVal &= ~CRYPT_EXPORT;
2430 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2431 ok(result ||
2432 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2433 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2434 "%08x\n", GetLastError());
2435 /* but it has no effect. */
2436 dwVal = 0xdeadbeef;
2437 dwLen = sizeof(DWORD);
2438 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2439 ok(result, "%08x\n", GetLastError());
2440 ok(dwVal ==
2441 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2442 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2443 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2444 " got %08x\n", dwVal);
2445 /* Thus, changing the export flag of the key doesn't affect whether the key
2446 * may be exported.
2448 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2449 ok(result, "%08x\n", GetLastError());
2451 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2452 ok (result, "%08x\n", GetLastError());
2454 /* A subsequent get of the same key, into a different handle, also doesn't
2455 * show that the permissions have been changed.
2457 dwVal = 0xdeadbeef;
2458 dwLen = sizeof(DWORD);
2459 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2460 ok(result, "%08x\n", GetLastError());
2461 ok(dwVal ==
2462 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2463 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2464 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2465 " got %08x\n", dwVal);
2467 CryptDestroyKey(hKey2);
2468 CryptDestroyKey(hKey1);
2470 clean_up_base_environment();
2473 static void test_key_initialization(void)
2475 DWORD dwLen;
2476 HCRYPTPROV prov1, prov2;
2477 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2478 BOOL result;
2479 static BYTE abSessionKey[148] = {
2480 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2481 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2482 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2483 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2484 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2485 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2486 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2487 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2488 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2489 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2490 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2491 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2492 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2493 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2494 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2495 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2496 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2497 0x04, 0x8c, 0x49, 0x92
2500 /* Like init_base_environment, but doesn't generate new keys, as they'll
2501 * be imported instead.
2503 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2505 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2506 CRYPT_NEWKEYSET);
2507 ok(result, "%08x\n", GetLastError());
2509 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2510 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2512 dwLen = (DWORD)sizeof(abSessionKey);
2513 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2514 ok(result, "%08x\n", GetLastError());
2516 /* Once the key has been imported, subsequently acquiring a context with
2517 * the same name will allow retrieving the key.
2519 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2520 ok(result, "%08x\n", GetLastError());
2521 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2522 ok(result, "%08x\n", GetLastError());
2523 if (result) CryptDestroyKey(hKey);
2524 CryptReleaseContext(prov2, 0);
2526 CryptDestroyKey(hSessionKey);
2527 CryptDestroyKey(hKeyExchangeKey);
2528 CryptReleaseContext(prov1, 0);
2529 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2530 CRYPT_DELETEKEYSET);
2533 START_TEST(rsaenh)
2535 if (!init_base_environment(0))
2536 return;
2537 test_prov();
2538 test_gen_random();
2539 test_hashes();
2540 test_rc4();
2541 test_rc2();
2542 test_des();
2543 test_3des112();
2544 test_3des();
2545 test_hmac();
2546 test_mac();
2547 test_block_cipher_modes();
2548 test_import_private();
2549 test_verify_signature();
2550 test_rsa_encrypt();
2551 test_import_export();
2552 test_enum_container();
2553 clean_up_base_environment();
2554 test_key_permissions();
2555 test_key_initialization();
2556 test_schannel_provider();
2557 test_null_provider();
2558 test_rsa_round_trip();
2559 if (!init_aes_environment())
2560 return;
2561 test_aes(128);
2562 test_aes(192);
2563 test_aes(256);
2564 clean_up_aes_environment();