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