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