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
25 #include "wine/test.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];
44 static const cryptdata cTestData
[4] = {
46 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
49 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
52 {'a','b','c','d','e','f','g','h',0},
55 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
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
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";
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
);
81 lstrcpy(unique
, szContainer_md5
);
83 lstrcat(unique
, guid
);
86 static void printBytes(const char *heading
, const BYTE
*pb
, size_t cb
)
89 printf("%s: ",heading
);
91 printf("0x%02x,",pb
[i
]);
95 static BOOL (WINAPI
*pCryptDuplicateHash
) (HCRYPTHASH
, DWORD
*, DWORD
, HCRYPTHASH
*);
98 static void trace_hex(BYTE *pbData, DWORD dwLen) {
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]);
108 for (j=0; i<dwLen; j++,i++) {
109 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
115 static int init_base_environment(void)
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
,
133 ok(result
, "%08x\n", GetLastError());
134 if (!result
) return 0;
135 result
= CryptGenKey(hProv
, AT_KEYEXCHANGE
, 0, &hKey
);
136 ok(result
, "%08x\n", GetLastError());
137 if (result
) CryptDestroyKey(hKey
);
138 result
= CryptGenKey(hProv
, AT_SIGNATURE
, 0, &hKey
);
139 ok(result
, "%08x\n", GetLastError());
140 if (result
) CryptDestroyKey(hKey
);
145 static void clean_up_base_environment(void)
149 result
= CryptReleaseContext(hProv
, 1);
150 ok(!result
&& GetLastError()==NTE_BAD_FLAGS
, "%08x\n", GetLastError());
152 CryptAcquireContext(&hProv
, szContainer
, szProvider
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
155 static int init_aes_environment(void)
160 pCryptDuplicateHash
= (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
162 hProv
= (HCRYPTPROV
)INVALID_HANDLE_VALUE
;
164 /* we are using NULL as provider name for RSA_AES provider as the provider
165 * names are different in Windows XP and Vista. Its different as to what
166 * its defined in the SDK on Windows XP.
167 * This provider is available on Windows XP, Windows 2003 and Vista. */
169 result
= CryptAcquireContext(&hProv
, szContainer
, NULL
, PROV_RSA_AES
, CRYPT_VERIFYCONTEXT
);
170 if (!result
&& GetLastError() == NTE_PROV_TYPE_NOT_DEF
)
172 win_skip("RSA_ASE provider not supported\n");
175 ok(!result
&& GetLastError()==NTE_BAD_FLAGS
, "%d, %08x\n", result
, GetLastError());
177 if (!CryptAcquireContext(&hProv
, szContainer
, NULL
, PROV_RSA_AES
, 0))
179 ok(GetLastError()==NTE_BAD_KEYSET
, "%08x\n", GetLastError());
180 if (GetLastError()!=NTE_BAD_KEYSET
) return 0;
181 result
= CryptAcquireContext(&hProv
, szContainer
, NULL
, PROV_RSA_AES
,
183 ok(result
, "%08x\n", GetLastError());
184 if (!result
) return 0;
185 result
= CryptGenKey(hProv
, AT_KEYEXCHANGE
, 0, &hKey
);
186 ok(result
, "%08x\n", GetLastError());
187 if (result
) CryptDestroyKey(hKey
);
188 result
= CryptGenKey(hProv
, AT_SIGNATURE
, 0, &hKey
);
189 ok(result
, "%08x\n", GetLastError());
190 if (result
) CryptDestroyKey(hKey
);
195 static void clean_up_aes_environment(void)
199 result
= CryptReleaseContext(hProv
, 1);
200 ok(!result
&& GetLastError()==NTE_BAD_FLAGS
, "%08x\n", GetLastError());
202 CryptAcquireContext(&hProv
, szContainer
, NULL
, PROV_RSA_AES
, CRYPT_DELETEKEYSET
);
205 static void test_prov(void)
210 dwLen
= (DWORD
)sizeof(DWORD
);
211 SetLastError(0xdeadbeef);
212 result
= CryptGetProvParam(hProv
, PP_SIG_KEYSIZE_INC
, (BYTE
*)&dwInc
, &dwLen
, 0);
213 if (!result
&& GetLastError() == NTE_BAD_TYPE
)
214 skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
216 ok(result
&& dwInc
==8, "%08x, %d\n", GetLastError(), dwInc
);
218 dwLen
= (DWORD
)sizeof(DWORD
);
219 SetLastError(0xdeadbeef);
220 result
= CryptGetProvParam(hProv
, PP_KEYX_KEYSIZE_INC
, (BYTE
*)&dwInc
, &dwLen
, 0);
221 if (!result
&& GetLastError() == NTE_BAD_TYPE
)
222 skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
224 ok(result
&& dwInc
==8, "%08x, %d\n", GetLastError(), dwInc
);
227 static void test_gen_random(void)
230 BYTE rnd1
[16], rnd2
[16];
232 memset(rnd1
, 0, sizeof(rnd1
));
233 memset(rnd2
, 0, sizeof(rnd2
));
235 result
= CryptGenRandom(hProv
, sizeof(rnd1
), rnd1
);
236 if (!result
&& GetLastError() == NTE_FAIL
) {
237 /* rsaenh compiled without OpenSSL */
241 ok(result
, "%08x\n", GetLastError());
243 result
= CryptGenRandom(hProv
, sizeof(rnd2
), rnd2
);
244 ok(result
, "%08x\n", GetLastError());
246 ok(memcmp(rnd1
, rnd2
, sizeof(rnd1
)), "CryptGenRandom generates non random data\n");
249 static BOOL
derive_key(ALG_ID aiAlgid
, HCRYPTKEY
*phKey
, DWORD len
)
253 unsigned char pbData
[2000];
257 for (i
=0; i
<2000; i
++) pbData
[i
] = (unsigned char)i
;
258 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
260 /* rsaenh compiled without OpenSSL */
261 ok(GetLastError()==NTE_BAD_ALGID
, "%08x\n", GetLastError());
264 ok(result
, "%08x\n", GetLastError());
265 if (!result
) return FALSE
;
266 result
= CryptHashData(hHash
, (BYTE
*)pbData
, sizeof(pbData
), 0);
267 ok(result
, "%08x\n", GetLastError());
268 if (!result
) return FALSE
;
269 result
= CryptDeriveKey(hProv
, aiAlgid
, hHash
, (len
<< 16) | CRYPT_EXPORTABLE
, phKey
);
270 ok(result
, "%08x\n", GetLastError());
271 if (!result
) return FALSE
;
273 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbData
, &len
, 0);
274 ok(result
, "%08x\n", GetLastError());
275 CryptDestroyHash(hHash
);
279 static void test_hashes(void)
281 static const unsigned char md2hash
[16] = {
282 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
283 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
284 static const unsigned char md4hash
[16] = {
285 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
286 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
287 static const unsigned char empty_md5hash
[16] = {
288 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
289 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
290 static const unsigned char md5hash
[16] = {
291 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
292 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
293 static const unsigned char sha1hash
[20] = {
294 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
295 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
296 unsigned char pbData
[2048];
298 HCRYPTHASH hHash
, hHashClone
;
299 BYTE pbHashValue
[36];
303 for (i
=0; i
<2048; i
++) pbData
[i
] = (unsigned char)i
;
306 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
308 /* rsaenh compiled without OpenSSL */
309 ok(GetLastError() == NTE_BAD_ALGID
, "%08x\n", GetLastError());
311 result
= CryptHashData(hHash
, (BYTE
*)pbData
, sizeof(pbData
), 0);
312 ok(result
, "%08x\n", GetLastError());
315 result
= CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
316 ok(result
&& (hashlen
== 16), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
319 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
320 ok(result
, "%08x\n", GetLastError());
322 ok(!memcmp(pbHashValue
, md2hash
, 16), "Wrong MD2 hash!\n");
324 result
= CryptDestroyHash(hHash
);
325 ok(result
, "%08x\n", GetLastError());
329 result
= CryptCreateHash(hProv
, CALG_MD4
, 0, 0, &hHash
);
330 ok(result
, "%08x\n", GetLastError());
332 result
= CryptHashData(hHash
, (BYTE
*)pbData
, sizeof(pbData
), 0);
333 ok(result
, "%08x\n", GetLastError());
336 result
= CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
337 ok(result
&& (hashlen
== 16), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
340 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
341 ok(result
, "%08x\n", GetLastError());
343 ok(!memcmp(pbHashValue
, md4hash
, 16), "Wrong MD4 hash!\n");
345 result
= CryptDestroyHash(hHash
);
346 ok(result
, "%08x\n", GetLastError());
349 result
= CryptCreateHash(hProv
, CALG_MD5
, 0, 0, &hHash
);
350 ok(result
, "%08x\n", GetLastError());
353 result
= CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
354 ok(result
&& (hashlen
== 16), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
356 result
= CryptHashData(hHash
, (BYTE
*)pbData
, sizeof(pbData
), 0);
357 ok(result
, "%08x\n", GetLastError());
360 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
361 ok(result
, "%08x\n", GetLastError());
363 ok(!memcmp(pbHashValue
, md5hash
, 16), "Wrong MD5 hash!\n");
365 result
= CryptDestroyHash(hHash
);
366 ok(result
, "%08x\n", GetLastError());
368 result
= CryptCreateHash(hProv
, CALG_MD5
, 0, 0, &hHash
);
369 ok(result
, "%08x\n", GetLastError());
371 /* The hash is available even if CryptHashData hasn't been called */
373 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
374 ok(result
, "%08x\n", GetLastError());
376 ok(!memcmp(pbHashValue
, empty_md5hash
, 16), "Wrong MD5 hash!\n");
378 /* It's also stable: getting it twice results in the same value */
379 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
380 ok(result
, "%08x\n", GetLastError());
382 ok(!memcmp(pbHashValue
, empty_md5hash
, 16), "Wrong MD5 hash!\n");
384 /* Can't add data after the hash been retrieved */
385 SetLastError(0xdeadbeef);
386 result
= CryptHashData(hHash
, (BYTE
*)pbData
, sizeof(pbData
), 0);
387 ok(!result
, "Expected failure\n");
388 ok(GetLastError() == NTE_BAD_HASH_STATE
||
389 GetLastError() == NTE_BAD_ALGID
, /* Win9x, WinMe, NT4 */
390 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
392 /* You can still retrieve the hash, its value just hasn't changed */
393 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
394 ok(result
, "%08x\n", GetLastError());
396 ok(!memcmp(pbHashValue
, empty_md5hash
, 16), "Wrong MD5 hash!\n");
398 result
= CryptDestroyHash(hHash
);
399 ok(result
, "%08x\n", GetLastError());
402 result
= CryptCreateHash(hProv
, CALG_SHA
, 0, 0, &hHash
);
403 ok(result
, "%08x\n", GetLastError());
405 result
= CryptHashData(hHash
, (BYTE
*)pbData
, 5, 0);
406 ok(result
, "%08x\n", GetLastError());
408 if(pCryptDuplicateHash
) {
409 result
= pCryptDuplicateHash(hHash
, 0, 0, &hHashClone
);
410 ok(result
, "%08x\n", GetLastError());
412 result
= CryptHashData(hHashClone
, (BYTE
*)pbData
+5, sizeof(pbData
)-5, 0);
413 ok(result
, "%08x\n", GetLastError());
416 result
= CryptGetHashParam(hHashClone
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
417 ok(result
&& (hashlen
== 20), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
420 result
= CryptGetHashParam(hHashClone
, HP_HASHVAL
, pbHashValue
, &len
, 0);
421 ok(result
, "%08x\n", GetLastError());
423 ok(!memcmp(pbHashValue
, sha1hash
, 20), "Wrong SHA1 hash!\n");
425 result
= CryptDestroyHash(hHashClone
);
426 ok(result
, "%08x\n", GetLastError());
429 result
= CryptDestroyHash(hHash
);
430 ok(result
, "%08x\n", GetLastError());
433 static void test_block_cipher_modes(void)
435 static const BYTE plain
[23] = {
436 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
437 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
438 static const BYTE ecb
[24] = {
439 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
440 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
441 static const BYTE cbc
[24] = {
442 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
443 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
444 static const BYTE cfb
[24] = {
445 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
446 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
452 result
= derive_key(CALG_RC2
, &hKey
, 40);
455 memcpy(abData
, plain
, sizeof(abData
));
457 dwMode
= CRYPT_MODE_ECB
;
458 result
= CryptSetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, 0);
459 ok(result
, "%08x\n", GetLastError());
462 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, NULL
, &dwLen
, 24);
463 ok(result
, "CryptEncrypt failed: %08x\n", GetLastError());
464 ok(dwLen
== 24, "Unexpected length %d\n", dwLen
);
466 SetLastError(ERROR_SUCCESS
);
468 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, abData
, &dwLen
, 24);
469 ok(result
&& dwLen
== 24 && !memcmp(ecb
, abData
, sizeof(ecb
)),
470 "%08x, dwLen: %d\n", GetLastError(), dwLen
);
472 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, abData
, &dwLen
);
473 ok(result
&& dwLen
== 23 && !memcmp(plain
, abData
, sizeof(plain
)),
474 "%08x, dwLen: %d\n", GetLastError(), dwLen
);
476 dwMode
= CRYPT_MODE_CBC
;
477 result
= CryptSetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, 0);
478 ok(result
, "%08x\n", GetLastError());
481 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, NULL
, &dwLen
, 24);
482 ok(result
, "CryptEncrypt failed: %08x\n", GetLastError());
483 ok(dwLen
== 24, "Unexpected length %d\n", dwLen
);
486 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, abData
, &dwLen
, 24);
487 ok(result
&& dwLen
== 24 && !memcmp(cbc
, abData
, sizeof(cbc
)),
488 "%08x, dwLen: %d\n", GetLastError(), dwLen
);
490 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, abData
, &dwLen
);
491 ok(result
&& dwLen
== 23 && !memcmp(plain
, abData
, sizeof(plain
)),
492 "%08x, dwLen: %d\n", GetLastError(), dwLen
);
494 dwMode
= CRYPT_MODE_CFB
;
495 result
= CryptSetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, 0);
496 ok(result
, "%08x\n", GetLastError());
499 result
= CryptEncrypt(hKey
, 0, FALSE
, 0, abData
, &dwLen
, 24);
500 ok(result
&& dwLen
== 16, "%08x, dwLen: %d\n", GetLastError(), dwLen
);
503 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, abData
+16, &dwLen
, 8);
504 ok(result
&& dwLen
== 8 && !memcmp(cfb
, abData
, sizeof(cfb
)),
505 "%08x, dwLen: %d\n", GetLastError(), dwLen
);
508 result
= CryptDecrypt(hKey
, 0, FALSE
, 0, abData
, &dwLen
);
509 ok(result
&& dwLen
== 8, "%08x, dwLen: %d\n", GetLastError(), dwLen
);
512 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, abData
+8, &dwLen
);
513 ok(result
&& dwLen
== 15 && !memcmp(plain
, abData
, sizeof(plain
)),
514 "%08x, dwLen: %d\n", GetLastError(), dwLen
);
516 dwMode
= CRYPT_MODE_OFB
;
517 result
= CryptSetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, 0);
518 ok(result
, "%08x\n", GetLastError());
521 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, abData
, &dwLen
, 24);
522 ok(!result
&& GetLastError() == NTE_BAD_ALGID
, "%08x\n", GetLastError());
524 CryptDestroyKey(hKey
);
527 static void test_3des112(void)
532 unsigned char pbData
[16];
535 result
= derive_key(CALG_3DES_112
, &hKey
, 0);
537 /* rsaenh compiled without OpenSSL */
538 ok(GetLastError() == NTE_BAD_ALGID
, "%08x\n", GetLastError());
542 for (i
=0; i
<sizeof(pbData
); i
++) pbData
[i
] = (unsigned char)i
;
545 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, 16);
546 ok(result
, "%08x\n", GetLastError());
548 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
549 ok(result
, "%08x\n", GetLastError());
553 memcpy(pbData
,cTestData
[i
].origstr
,cTestData
[i
].strlen
);
555 dwLen
= cTestData
[i
].enclen
;
556 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, cTestData
[i
].buflen
);
557 ok(result
, "%08x\n", GetLastError());
558 ok(dwLen
==cTestData
[i
].buflen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].buflen
);
560 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
561 ok(result
, "%08x\n", GetLastError());
562 ok(dwLen
==cTestData
[i
].enclen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].enclen
);
563 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[1].enclen
)==0,"decryption incorrect %d\n",i
);
564 if((dwLen
!= cTestData
[i
].enclen
) ||
565 memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
))
567 printBytes("expected",cTestData
[i
].decstr
,cTestData
[i
].strlen
);
568 printBytes("got",pbData
,dwLen
);
571 result
= CryptDestroyKey(hKey
);
572 ok(result
, "%08x\n", GetLastError());
575 static void test_des(void)
580 unsigned char pbData
[16];
583 result
= derive_key(CALG_DES
, &hKey
, 56);
585 /* rsaenh compiled without OpenSSL */
586 ok(GetLastError()==NTE_BAD_ALGID
, "%08x\n", GetLastError());
590 dwMode
= CRYPT_MODE_ECB
;
591 result
= CryptSetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, 0);
592 ok(result
, "%08x\n", GetLastError());
594 dwLen
= sizeof(DWORD
);
595 result
= CryptGetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, &dwLen
, 0);
596 ok(result
, "%08x\n", GetLastError());
598 for (i
=0; i
<sizeof(pbData
); i
++) pbData
[i
] = (unsigned char)i
;
601 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, 16);
602 ok(result
, "%08x\n", GetLastError());
604 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
605 ok(result
, "%08x\n", GetLastError());
609 memcpy(pbData
,cTestData
[i
].origstr
,cTestData
[i
].strlen
);
611 dwLen
= cTestData
[i
].enclen
;
612 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, cTestData
[i
].buflen
);
613 ok(result
, "%08x\n", GetLastError());
614 ok(dwLen
==cTestData
[i
].buflen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].buflen
);
616 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
617 ok(result
, "%08x\n", GetLastError());
618 ok(dwLen
==cTestData
[i
].enclen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].enclen
);
619 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
)==0,"decryption incorrect %d\n",i
);
620 if((dwLen
!= cTestData
[i
].enclen
) ||
621 memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
))
623 printBytes("expected",cTestData
[i
].decstr
,cTestData
[i
].strlen
);
624 printBytes("got",pbData
,dwLen
);
628 result
= CryptDestroyKey(hKey
);
629 ok(result
, "%08x\n", GetLastError());
632 static void test_3des(void)
637 unsigned char pbData
[16];
638 static const BYTE des3
[16] = {
639 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
640 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
643 result
= derive_key(CALG_3DES
, &hKey
, 0);
646 for (i
=0; i
<sizeof(pbData
); i
++) pbData
[i
] = (unsigned char)i
;
649 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, 16);
650 ok(result
, "%08x\n", GetLastError());
652 ok(!memcmp(pbData
, des3
, sizeof(des3
)), "3DES encryption failed!\n");
654 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
655 ok(result
, "%08x\n", GetLastError());
659 memcpy(pbData
,cTestData
[i
].origstr
,cTestData
[i
].strlen
);
661 dwLen
= cTestData
[i
].enclen
;
662 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, cTestData
[i
].buflen
);
663 ok(result
, "%08x\n", GetLastError());
664 ok(dwLen
==cTestData
[i
].buflen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].buflen
);
666 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
667 ok(result
, "%08x\n", GetLastError());
668 ok(dwLen
==cTestData
[i
].enclen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].enclen
);
669 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
)==0,"decryption incorrect %d\n",i
);
670 if((dwLen
!= cTestData
[i
].enclen
) ||
671 memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
))
673 printBytes("expected",cTestData
[i
].decstr
,cTestData
[i
].strlen
);
674 printBytes("got",pbData
,dwLen
);
677 result
= CryptDestroyKey(hKey
);
678 ok(result
, "%08x\n", GetLastError());
681 static void test_aes(int keylen
)
686 unsigned char pbData
[16];
692 result
= derive_key(CALG_AES_256
, &hKey
, 0);
695 result
= derive_key(CALG_AES_192
, &hKey
, 0);
699 result
= derive_key(CALG_AES_128
, &hKey
, 0);
704 for (i
=0; i
<sizeof(pbData
); i
++) pbData
[i
] = (unsigned char)i
;
707 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, 16);
708 ok(result
, "%08x\n", GetLastError());
710 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
711 ok(result
, "%08x\n", GetLastError());
715 memcpy(pbData
,cTestData
[i
].origstr
,cTestData
[i
].strlen
);
717 dwLen
= cTestData
[i
].enclen
;
718 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, cTestData
[i
].buflen
);
719 ok(result
, "%08x\n", GetLastError());
720 ok(dwLen
==cTestData
[i
].buflen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].buflen
);
722 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
723 ok(result
, "%08x\n", GetLastError());
724 ok(dwLen
==cTestData
[i
].enclen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].enclen
);
725 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[1].enclen
)==0,"decryption incorrect %d\n",i
);
726 if((dwLen
!= cTestData
[i
].enclen
) ||
727 memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
))
729 printBytes("expected",cTestData
[i
].decstr
,cTestData
[i
].strlen
);
730 printBytes("got",pbData
,dwLen
);
733 result
= CryptDestroyKey(hKey
);
734 ok(result
, "%08x\n", GetLastError());
737 static void test_rc2(void)
739 static const BYTE rc2_40_encrypted
[16] = {
740 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
741 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
742 static const BYTE rc2_128_encrypted
[] = {
743 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
748 DWORD dwLen
, dwKeyLen
, dwDataLen
, dwMode
, dwModeBits
;
750 unsigned char pbData
[2000], pbHashValue
[16];
753 for (i
=0; i
<2000; i
++) pbData
[i
] = (unsigned char)i
;
756 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
758 ok(GetLastError()==NTE_BAD_ALGID
, "%08x\n", GetLastError());
760 CRYPT_INTEGER_BLOB salt
;
762 result
= CryptHashData(hHash
, (BYTE
*)pbData
, sizeof(pbData
), 0);
763 ok(result
, "%08x\n", GetLastError());
766 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &dwLen
, 0);
767 ok(result
, "%08x\n", GetLastError());
769 result
= CryptDeriveKey(hProv
, CALG_RC2
, hHash
, 40 << 16, &hKey
);
770 ok(result
, "%08x\n", GetLastError());
772 dwLen
= sizeof(DWORD
);
773 result
= CryptGetKeyParam(hKey
, KP_KEYLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
774 ok(result
, "%08x\n", GetLastError());
776 dwMode
= CRYPT_MODE_CBC
;
777 result
= CryptSetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, 0);
778 ok(result
, "%08x\n", GetLastError());
780 dwLen
= sizeof(DWORD
);
781 result
= CryptGetKeyParam(hKey
, KP_MODE_BITS
, (BYTE
*)&dwModeBits
, &dwLen
, 0);
782 ok(result
, "%08x\n", GetLastError());
784 dwLen
= sizeof(DWORD
);
785 result
= CryptGetKeyParam(hKey
, KP_PERMISSIONS
, (BYTE
*)&dwModeBits
, &dwLen
, 0);
786 ok(result
, "%08x\n", GetLastError());
788 dwLen
= sizeof(DWORD
);
789 result
= CryptGetKeyParam(hKey
, KP_BLOCKLEN
, (BYTE
*)&dwModeBits
, &dwLen
, 0);
790 ok(result
, "%08x\n", GetLastError());
792 result
= CryptGetKeyParam(hKey
, KP_IV
, NULL
, &dwLen
, 0);
793 ok(result
, "%08x\n", GetLastError());
794 pbTemp
= HeapAlloc(GetProcessHeap(), 0, dwLen
);
795 CryptGetKeyParam(hKey
, KP_IV
, pbTemp
, &dwLen
, 0);
796 HeapFree(GetProcessHeap(), 0, pbTemp
);
798 result
= CryptGetKeyParam(hKey
, KP_SALT
, NULL
, &dwLen
, 0);
799 ok(result
, "%08x\n", GetLastError());
800 pbTemp
= HeapAlloc(GetProcessHeap(), 0, dwLen
);
801 CryptGetKeyParam(hKey
, KP_SALT
, pbTemp
, &dwLen
, 0);
802 HeapFree(GetProcessHeap(), 0, pbTemp
);
804 dwLen
= sizeof(DWORD
);
805 CryptGetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, &dwLen
, 0);
807 result
= CryptDestroyHash(hHash
);
808 ok(result
, "%08x\n", GetLastError());
811 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwDataLen
, 24);
812 ok(result
, "%08x\n", GetLastError());
814 ok(!memcmp(pbData
, rc2_40_encrypted
, 16), "RC2 encryption failed!\n");
816 result
= CryptGetKeyParam(hKey
, KP_IV
, NULL
, &dwLen
, 0);
817 ok(result
, "%08x\n", GetLastError());
818 pbTemp
= HeapAlloc(GetProcessHeap(), 0, dwLen
);
819 CryptGetKeyParam(hKey
, KP_IV
, pbTemp
, &dwLen
, 0);
820 HeapFree(GetProcessHeap(), 0, pbTemp
);
822 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwDataLen
);
823 ok(result
, "%08x\n", GetLastError());
825 /* What sizes salt can I set? */
826 salt
.pbData
= pbData
;
830 result
= CryptSetKeyParam(hKey
, KP_SALT_EX
, (BYTE
*)&salt
, 0);
831 ok(result
, "setting salt failed for size %d: %08x\n", i
, GetLastError());
834 SetLastError(0xdeadbeef);
835 result
= CryptSetKeyParam(hKey
, KP_SALT_EX
, (BYTE
*)&salt
, 0);
837 broken(result
), /* Win9x, WinMe, NT4, W2K */
838 "%08x\n", GetLastError());
840 result
= CryptDestroyKey(hKey
);
841 ok(result
, "%08x\n", GetLastError());
844 /* Again, but test setting the effective key len */
845 for (i
=0; i
<2000; i
++) pbData
[i
] = (unsigned char)i
;
847 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
849 ok(GetLastError()==NTE_BAD_ALGID
, "%08x\n", GetLastError());
851 result
= CryptHashData(hHash
, (BYTE
*)pbData
, sizeof(pbData
), 0);
852 ok(result
, "%08x\n", GetLastError());
855 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &dwLen
, 0);
856 ok(result
, "%08x\n", GetLastError());
858 result
= CryptDeriveKey(hProv
, CALG_RC2
, hHash
, 56 << 16, &hKey
);
859 ok(result
, "%08x\n", GetLastError());
861 SetLastError(0xdeadbeef);
862 result
= CryptSetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, NULL
, 0);
863 ok(!result
&& GetLastError()==ERROR_INVALID_PARAMETER
, "%08x\n", GetLastError());
865 SetLastError(0xdeadbeef);
866 result
= CryptSetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (LPBYTE
)&dwKeyLen
, 0);
867 ok(!result
&& GetLastError()==NTE_BAD_DATA
, "%08x\n", GetLastError());
869 SetLastError(0xdeadbeef);
870 result
= CryptSetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (LPBYTE
)&dwKeyLen
, 0);
872 dwLen
= sizeof(dwKeyLen
);
873 CryptGetKeyParam(hKey
, KP_KEYLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
874 ok(dwKeyLen
== 56, "%d (%08x)\n", dwKeyLen
, GetLastError());
875 CryptGetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
876 ok(dwKeyLen
== 56 || broken(dwKeyLen
== 40), "%d (%08x)\n", dwKeyLen
, GetLastError());
879 result
= CryptSetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (LPBYTE
)&dwKeyLen
, 0);
880 ok(result
, "%d\n", GetLastError());
882 dwLen
= sizeof(dwKeyLen
);
883 CryptGetKeyParam(hKey
, KP_KEYLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
884 ok(dwKeyLen
== 56, "%d (%08x)\n", dwKeyLen
, GetLastError());
885 CryptGetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
886 ok(dwKeyLen
== 128, "%d (%08x)\n", dwKeyLen
, GetLastError());
888 result
= CryptDestroyHash(hHash
);
889 ok(result
, "%08x\n", GetLastError());
892 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwDataLen
, 24);
893 ok(result
, "%08x\n", GetLastError());
895 ok(!memcmp(pbData
, rc2_128_encrypted
, sizeof(rc2_128_encrypted
)),
896 "RC2 encryption failed!\n");
898 /* Oddly enough this succeeds, though it should have no effect */
900 result
= CryptSetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (LPBYTE
)&dwKeyLen
, 0);
901 ok(result
, "%d\n", GetLastError());
903 result
= CryptDestroyKey(hKey
);
904 ok(result
, "%08x\n", GetLastError());
908 static void test_rc4(void)
910 static const BYTE rc4
[16] = {
911 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
912 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
916 DWORD dwDataLen
= 5, dwKeyLen
, dwLen
= sizeof(DWORD
), dwMode
;
917 unsigned char pbData
[2000], *pbTemp
;
918 unsigned char pszBuffer
[256];
921 for (i
=0; i
<2000; i
++) pbData
[i
] = (unsigned char)i
;
924 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
926 /* rsaenh compiled without OpenSSL */
927 ok(GetLastError() == NTE_BAD_ALGID
, "%08x\n", GetLastError());
929 CRYPT_INTEGER_BLOB salt
;
931 result
= CryptHashData(hHash
, (BYTE
*)pbData
, sizeof(pbData
), 0);
932 ok(result
, "%08x\n", GetLastError());
935 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pszBuffer
, &dwLen
, 0);
936 ok(result
, "%08x\n", GetLastError());
938 result
= CryptDeriveKey(hProv
, CALG_RC4
, hHash
, 56 << 16, &hKey
);
939 ok(result
, "%08x\n", GetLastError());
941 dwLen
= sizeof(DWORD
);
942 result
= CryptGetKeyParam(hKey
, KP_KEYLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
943 ok(result
, "%08x\n", GetLastError());
945 dwLen
= sizeof(DWORD
);
946 result
= CryptGetKeyParam(hKey
, KP_BLOCKLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
947 ok(result
, "%08x\n", GetLastError());
949 result
= CryptGetKeyParam(hKey
, KP_IV
, NULL
, &dwLen
, 0);
950 ok(result
, "%08x\n", GetLastError());
951 pbTemp
= HeapAlloc(GetProcessHeap(), 0, dwLen
);
952 CryptGetKeyParam(hKey
, KP_IV
, pbTemp
, &dwLen
, 0);
953 HeapFree(GetProcessHeap(), 0, pbTemp
);
955 result
= CryptGetKeyParam(hKey
, KP_SALT
, NULL
, &dwLen
, 0);
956 ok(result
, "%08x\n", GetLastError());
957 pbTemp
= HeapAlloc(GetProcessHeap(), 0, dwLen
);
958 CryptGetKeyParam(hKey
, KP_SALT
, pbTemp
, &dwLen
, 0);
959 HeapFree(GetProcessHeap(), 0, pbTemp
);
961 dwLen
= sizeof(DWORD
);
962 CryptGetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, &dwLen
, 0);
964 result
= CryptDestroyHash(hHash
);
965 ok(result
, "%08x\n", GetLastError());
968 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, NULL
, &dwDataLen
, 24);
969 ok(result
, "%08x\n", GetLastError());
971 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwDataLen
, 24);
972 ok(result
, "%08x\n", GetLastError());
974 ok(!memcmp(pbData
, rc4
, dwDataLen
), "RC4 encryption failed!\n");
976 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwDataLen
);
977 ok(result
, "%08x\n", GetLastError());
979 /* What sizes salt can I set? */
980 salt
.pbData
= pbData
;
984 result
= CryptSetKeyParam(hKey
, KP_SALT_EX
, (BYTE
*)&salt
, 0);
985 ok(result
, "setting salt failed for size %d: %08x\n", i
, GetLastError());
988 SetLastError(0xdeadbeef);
989 result
= CryptSetKeyParam(hKey
, KP_SALT_EX
, (BYTE
*)&salt
, 0);
991 broken(result
), /* Win9x, WinMe, NT4, W2K */
992 "%08x\n", GetLastError());
994 result
= CryptDestroyKey(hKey
);
995 ok(result
, "%08x\n", GetLastError());
999 static void test_hmac(void) {
1003 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1004 HMAC_INFO hmacInfo
= { CALG_MD5
, NULL
, 0, NULL
, 0 };
1007 static const BYTE hmac
[16] = {
1008 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1009 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1012 for (i
=0; i
<sizeof(abData
)/sizeof(BYTE
); i
++) abData
[i
] = (BYTE
)i
;
1014 if (!derive_key(CALG_RC2
, &hKey
, 56)) return;
1016 result
= CryptCreateHash(hProv
, CALG_HMAC
, hKey
, 0, &hHash
);
1017 ok(result
, "%08x\n", GetLastError());
1018 if (!result
) return;
1020 result
= CryptSetHashParam(hHash
, HP_HMAC_INFO
, (BYTE
*)&hmacInfo
, 0);
1021 ok(result
, "%08x\n", GetLastError());
1023 result
= CryptHashData(hHash
, (BYTE
*)abData
, sizeof(abData
), 0);
1024 ok(result
, "%08x\n", GetLastError());
1026 dwLen
= sizeof(abData
)/sizeof(BYTE
);
1027 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, abData
, &dwLen
, 0);
1028 ok(result
, "%08x\n", GetLastError());
1030 ok(!memcmp(abData
, hmac
, sizeof(hmac
)), "HMAC failed!\n");
1032 result
= CryptDestroyHash(hHash
);
1033 ok(result
, "%08x\n", GetLastError());
1035 result
= CryptDestroyKey(hKey
);
1036 ok(result
, "%08x\n", GetLastError());
1038 /* Provoke errors */
1039 result
= CryptCreateHash(hProv
, CALG_HMAC
, 0, 0, &hHash
);
1040 ok(!result
&& GetLastError() == NTE_BAD_KEY
, "%08x\n", GetLastError());
1043 static void test_mac(void) {
1048 BYTE abData
[256], abEnc
[264];
1049 static const BYTE mac_40
[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1052 for (i
=0; i
<sizeof(abData
)/sizeof(BYTE
); i
++) abData
[i
] = (BYTE
)i
;
1053 for (i
=0; i
<sizeof(abData
)/sizeof(BYTE
); i
++) abEnc
[i
] = (BYTE
)i
;
1055 if (!derive_key(CALG_RC2
, &hKey
, 40)) return;
1058 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, abEnc
, &dwLen
, 264);
1059 ok (result
&& dwLen
== 264, "%08x, dwLen: %d\n", GetLastError(), dwLen
);
1061 result
= CryptCreateHash(hProv
, CALG_MAC
, hKey
, 0, &hHash
);
1062 ok(result
, "%08x\n", GetLastError());
1063 if (!result
) return;
1065 result
= CryptHashData(hHash
, (BYTE
*)abData
, sizeof(abData
), 0);
1066 ok(result
, "%08x\n", GetLastError());
1068 dwLen
= sizeof(abData
)/sizeof(BYTE
);
1069 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, abData
, &dwLen
, 0);
1070 ok(result
&& dwLen
== 8, "%08x, dwLen: %d\n", GetLastError(), dwLen
);
1072 ok(!memcmp(abData
, mac_40
, sizeof(mac_40
)), "MAC failed!\n");
1074 result
= CryptDestroyHash(hHash
);
1075 ok(result
, "%08x\n", GetLastError());
1077 result
= CryptDestroyKey(hKey
);
1078 ok(result
, "%08x\n", GetLastError());
1080 /* Provoke errors */
1081 if (!derive_key(CALG_RC4
, &hKey
, 56)) return;
1083 SetLastError(0xdeadbeef);
1084 result
= CryptCreateHash(hProv
, CALG_MAC
, hKey
, 0, &hHash
);
1085 ok((!result
&& GetLastError() == NTE_BAD_KEY
) ||
1086 broken(result
), /* Win9x, WinMe, NT4, W2K */
1087 "%08x\n", GetLastError());
1089 result
= CryptDestroyKey(hKey
);
1090 ok(result
, "%08x\n", GetLastError());
1093 static BYTE abPlainPrivateKey
[596] = {
1094 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1095 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1096 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1097 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1098 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1099 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1100 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1101 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1102 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1103 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1104 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1105 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1106 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1107 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1108 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1109 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1110 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1111 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1112 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1113 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1114 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1115 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1116 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1117 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1118 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1119 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1120 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1121 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1122 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1123 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1124 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1125 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1126 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1127 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1128 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1129 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1130 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1131 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1132 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1133 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1134 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1135 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1136 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1137 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1138 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1139 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1140 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1141 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1142 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1143 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1144 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1145 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1146 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1147 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1148 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1149 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1150 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1151 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1152 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1153 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1154 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1155 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1156 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1157 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1158 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1159 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1160 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1161 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1162 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1163 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1164 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1165 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1166 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1167 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1168 0xf2, 0x5d, 0x58, 0x07
1171 static void test_import_private(void)
1174 HCRYPTKEY hKeyExchangeKey
, hSessionKey
;
1176 static BYTE abSessionKey
[148] = {
1177 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1178 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1179 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1180 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1181 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1182 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1183 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1184 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1185 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1186 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1187 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1188 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1189 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1190 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1191 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1192 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1193 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1194 0x04, 0x8c, 0x49, 0x92
1196 static BYTE abEncryptedMessage
[12] = {
1197 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1198 0x1c, 0xfd, 0xde, 0x71
1201 dwLen
= (DWORD
)sizeof(abPlainPrivateKey
);
1202 result
= CryptImportKey(hProv
, abPlainPrivateKey
, dwLen
, 0, 0, &hKeyExchangeKey
);
1204 /* rsaenh compiled without OpenSSL */
1205 ok(GetLastError() == NTE_FAIL
, "%08x\n", GetLastError());
1209 dwLen
= (DWORD
)sizeof(abSessionKey
);
1210 result
= CryptImportKey(hProv
, abSessionKey
, dwLen
, hKeyExchangeKey
, 0, &hSessionKey
);
1211 ok(result
, "%08x\n", GetLastError());
1212 if (!result
) return;
1214 dwLen
= (DWORD
)sizeof(abEncryptedMessage
);
1215 result
= CryptDecrypt(hSessionKey
, 0, TRUE
, 0, abEncryptedMessage
, &dwLen
);
1216 ok(result
&& dwLen
== 12 && !memcmp(abEncryptedMessage
, "Wine rocks!",12),
1217 "%08x, len: %d\n", GetLastError(), dwLen
);
1218 CryptDestroyKey(hSessionKey
);
1220 if (!derive_key(CALG_RC4
, &hSessionKey
, 56)) return;
1222 dwLen
= (DWORD
)sizeof(abSessionKey
);
1223 result
= CryptExportKey(hSessionKey
, hKeyExchangeKey
, SIMPLEBLOB
, 0, abSessionKey
, &dwLen
);
1224 ok(result
, "%08x\n", GetLastError());
1225 CryptDestroyKey(hSessionKey
);
1226 if (!result
) return;
1228 dwLen
= (DWORD
)sizeof(abSessionKey
);
1229 result
= CryptImportKey(hProv
, abSessionKey
, dwLen
, hKeyExchangeKey
, 0, &hSessionKey
);
1230 ok(result
, "%08x\n", GetLastError());
1231 if (!result
) return;
1233 CryptDestroyKey(hSessionKey
);
1234 CryptDestroyKey(hKeyExchangeKey
);
1237 static void test_verify_signature(void) {
1239 HCRYPTKEY hPubSignKey
;
1240 BYTE abData
[] = "Wine rocks!";
1242 BYTE abPubKey
[148] = {
1243 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1244 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1245 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1246 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1247 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1248 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1249 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1250 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1251 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1252 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1253 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1254 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1255 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1256 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1257 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1258 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1259 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1260 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1261 0xe1, 0x21, 0x50, 0xac
1263 /* md2 with hash oid */
1264 BYTE abSignatureMD2
[128] = {
1265 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1266 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1267 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1268 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1269 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1270 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1271 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1272 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1273 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1274 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1275 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1276 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1277 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1278 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1279 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1280 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1282 /* md2 without hash oid */
1283 BYTE abSignatureMD2NoOID
[128] = {
1284 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1285 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1286 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1287 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1288 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1289 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1290 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1291 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1292 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1293 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1294 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1295 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1296 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1297 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1298 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1299 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1301 /* md4 with hash oid */
1302 BYTE abSignatureMD4
[128] = {
1303 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1304 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1305 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1306 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1307 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1308 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1309 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1310 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1311 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1312 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1313 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1314 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1315 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1316 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1317 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1318 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1320 /* md4 without hash oid */
1321 BYTE abSignatureMD4NoOID
[128] = {
1322 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1323 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1324 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1325 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1326 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1327 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1328 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1329 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1330 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1331 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1332 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1333 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1334 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1335 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1336 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1337 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1339 /* md5 with hash oid */
1340 BYTE abSignatureMD5
[128] = {
1341 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1342 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1343 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1344 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1345 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1346 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1347 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1348 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1349 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1350 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1351 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1352 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1353 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1354 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1355 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1356 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1358 /* md5 without hash oid */
1359 BYTE abSignatureMD5NoOID
[128] = {
1360 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1361 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1362 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1363 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1364 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1365 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1366 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1367 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1368 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1369 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1370 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1371 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1372 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1373 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1374 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1375 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1377 /* sha with hash oid */
1378 BYTE abSignatureSHA
[128] = {
1379 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1380 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1381 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1382 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1383 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1384 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1385 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1386 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1387 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1388 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1389 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1390 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1391 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1392 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1393 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1394 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1396 /* sha without hash oid */
1397 BYTE abSignatureSHANoOID
[128] = {
1398 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1399 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1400 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1401 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1402 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1403 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1404 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1405 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1406 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1407 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1408 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1409 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1410 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1411 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1412 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1413 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1416 result
= CryptImportKey(hProv
, abPubKey
, 148, 0, 0, &hPubSignKey
);
1417 ok(result
, "%08x\n", GetLastError());
1418 if (!result
) return;
1420 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
1421 ok(result
, "%08x\n", GetLastError());
1422 if (!result
) return;
1424 result
= CryptHashData(hHash
, abData
, (DWORD
)sizeof(abData
), 0);
1425 ok(result
, "%08x\n", GetLastError());
1426 if (!result
) return;
1428 /*check that a NULL pointer signature is correctly handled*/
1429 result
= CryptVerifySignature(hHash
, NULL
, 128, hPubSignKey
, NULL
, 0);
1430 ok(!result
&& ERROR_INVALID_PARAMETER
== GetLastError(),
1431 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1434 /* check that we get a bad signature error when the signature is too short*/
1435 result
= CryptVerifySignature(hHash
, abSignatureMD2
, 64, hPubSignKey
, NULL
, 0);
1437 (NTE_BAD_SIGNATURE
== GetLastError() ||
1438 ERROR_INVALID_PARAMETER
== GetLastError()),
1439 "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
1443 result
= CryptVerifySignature(hHash
, abSignatureMD2
, 128, hPubSignKey
, NULL
, 0);
1444 ok(result
, "%08x\n", GetLastError());
1445 if (!result
) return;
1447 result
= CryptVerifySignature(hHash
, abSignatureMD2NoOID
, 128, hPubSignKey
, NULL
, CRYPT_NOHASHOID
);
1448 ok(result
, "%08x\n", GetLastError());
1449 if (!result
) return;
1451 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1452 * the OID at all. */
1453 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1454 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1455 if (result) return;*/
1457 CryptDestroyHash(hHash
);
1459 result
= CryptCreateHash(hProv
, CALG_MD4
, 0, 0, &hHash
);
1460 ok(result
, "%08x\n", GetLastError());
1461 if (!result
) return;
1463 result
= CryptHashData(hHash
, abData
, (DWORD
)sizeof(abData
), 0);
1464 ok(result
, "%08x\n", GetLastError());
1465 if (!result
) return;
1467 result
= CryptVerifySignature(hHash
, abSignatureMD4
, 128, hPubSignKey
, NULL
, 0);
1468 ok(result
, "%08x\n", GetLastError());
1469 if (!result
) return;
1471 result
= CryptVerifySignature(hHash
, abSignatureMD4NoOID
, 128, hPubSignKey
, NULL
, CRYPT_NOHASHOID
);
1472 ok(result
, "%08x\n", GetLastError());
1473 if (!result
) return;
1475 CryptDestroyHash(hHash
);
1477 result
= CryptCreateHash(hProv
, CALG_MD5
, 0, 0, &hHash
);
1478 ok(result
, "%08x\n", GetLastError());
1479 if (!result
) return;
1481 result
= CryptHashData(hHash
, abData
, (DWORD
)sizeof(abData
), 0);
1482 ok(result
, "%08x\n", GetLastError());
1483 if (!result
) return;
1485 result
= CryptVerifySignature(hHash
, abSignatureMD5
, 128, hPubSignKey
, NULL
, 0);
1486 ok(result
, "%08x\n", GetLastError());
1487 if (!result
) return;
1489 result
= CryptVerifySignature(hHash
, abSignatureMD5NoOID
, 128, hPubSignKey
, NULL
, CRYPT_NOHASHOID
);
1490 ok(result
, "%08x\n", GetLastError());
1491 if (!result
) return;
1493 CryptDestroyHash(hHash
);
1495 result
= CryptCreateHash(hProv
, CALG_SHA
, 0, 0, &hHash
);
1496 ok(result
, "%08x\n", GetLastError());
1497 if (!result
) return;
1499 result
= CryptHashData(hHash
, abData
, (DWORD
)sizeof(abData
), 0);
1500 ok(result
, "%08x\n", GetLastError());
1501 if (!result
) return;
1503 result
= CryptVerifySignature(hHash
, abSignatureSHA
, 128, hPubSignKey
, NULL
, 0);
1504 ok(result
, "%08x\n", GetLastError());
1505 if (!result
) return;
1507 result
= CryptVerifySignature(hHash
, abSignatureSHANoOID
, 128, hPubSignKey
, NULL
, CRYPT_NOHASHOID
);
1508 ok(result
, "%08x\n", GetLastError());
1509 if (!result
) return;
1511 CryptDestroyHash(hHash
);
1512 CryptDestroyKey(hPubSignKey
);
1515 static void test_rsa_encrypt(void)
1518 BYTE abData
[2048] = "Wine rocks!";
1522 /* It is allowed to use the key exchange key for encryption/decryption */
1523 result
= CryptGetUserKey(hProv
, AT_KEYEXCHANGE
, &hRSAKey
);
1524 ok (result
, "%08x\n", GetLastError());
1525 if (!result
) return;
1528 result
= CryptEncrypt(hRSAKey
, 0, TRUE
, 0, NULL
, &dwLen
, (DWORD
)sizeof(abData
));
1529 ok(result
, "CryptEncrypt failed: %08x\n", GetLastError());
1530 ok(dwLen
== 128, "Unexpected length %d\n", dwLen
);
1532 result
= CryptEncrypt(hRSAKey
, 0, TRUE
, 0, abData
, &dwLen
, (DWORD
)sizeof(abData
));
1533 ok (result
, "%08x\n", GetLastError());
1534 if (!result
) return;
1536 result
= CryptDecrypt(hRSAKey
, 0, TRUE
, 0, abData
, &dwLen
);
1537 ok (result
&& dwLen
== 12 && !memcmp(abData
, "Wine rocks!", 12), "%08x\n", GetLastError());
1539 CryptDestroyKey(hRSAKey
);
1541 /* It is not allowed to use the signature key for encryption/decryption */
1542 result
= CryptGetUserKey(hProv
, AT_SIGNATURE
, &hRSAKey
);
1543 ok (result
, "%08x\n", GetLastError());
1544 if (!result
) return;
1547 result
= CryptEncrypt(hRSAKey
, 0, TRUE
, 0, abData
, &dwLen
, (DWORD
)sizeof(abData
));
1548 ok (!result
&& GetLastError() == NTE_BAD_KEY
, "%08x\n", GetLastError());
1550 CryptDestroyKey(hRSAKey
);
1553 static void test_import_export(void)
1555 DWORD dwLen
, dwDataLen
;
1556 HCRYPTKEY hPublicKey
;
1559 BYTE emptyKey
[2048];
1560 static BYTE abPlainPublicKey
[84] = {
1561 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1562 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1563 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1564 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1565 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1566 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1567 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1568 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1569 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1570 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1571 0x11, 0x11, 0x11, 0x11
1575 result
= CryptImportKey(hProv
, abPlainPublicKey
, dwLen
, 0, 0, &hPublicKey
);
1576 ok(result
, "failed to import the public key\n");
1578 dwDataLen
=sizeof(algID
);
1579 result
= CryptGetKeyParam(hPublicKey
, KP_ALGID
, (LPBYTE
)&algID
, &dwDataLen
, 0);
1580 ok(result
, "failed to get the KP_ALGID from the imported public key\n");
1581 ok(algID
== CALG_RSA_KEYX
, "Expected CALG_RSA_KEYX, got %x\n", algID
);
1583 result
= CryptExportKey(hPublicKey
, 0, PUBLICKEYBLOB
, 0, emptyKey
, &dwLen
);
1584 ok(result
, "failed to export the fresh imported public key\n");
1585 ok(dwLen
== 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen
);
1586 ok(!memcmp(emptyKey
, abPlainPublicKey
, dwLen
), "exported key is different from the imported key\n");
1588 CryptDestroyKey(hPublicKey
);
1591 static void test_schannel_provider(void)
1594 HCRYPTKEY hRSAKey
, hMasterSecret
, hServerWriteKey
, hServerWriteMACKey
;
1595 HCRYPTHASH hMasterHash
, hTLS1PRF
, hHMAC
;
1598 SCHANNEL_ALG saSChannelAlg
;
1599 CRYPT_DATA_BLOB data_blob
;
1600 HMAC_INFO hmacInfo
= { CALG_MD5
, NULL
, 0, NULL
, 0 };
1601 BYTE abTLS1Master
[140] = {
1602 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1603 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1604 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1605 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1606 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1607 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1608 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1609 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1610 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1611 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1612 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1613 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1614 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1615 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1616 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1617 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1618 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1619 0xd3, 0x1e, 0x82, 0xb3
1621 BYTE abServerSecret
[33] = "Super Secret Server Secret 12345";
1622 BYTE abClientSecret
[33] = "Super Secret Client Secret 12345";
1623 BYTE abHashedHandshakes
[37] = "123456789012345678901234567890123456";
1624 BYTE abClientFinished
[16] = "client finished";
1625 BYTE abData
[16] = "Wine rocks!";
1627 static const BYTE abEncryptedData
[16] = {
1628 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1629 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1631 static const BYTE abPRF
[16] = {
1632 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1633 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1635 static const BYTE abMD5
[16] = {
1636 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1637 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1640 result
= CryptAcquireContext(&hProv
, NULL
, NULL
, PROV_RSA_SCHANNEL
, CRYPT_VERIFYCONTEXT
|CRYPT_NEWKEYSET
);
1643 win_skip("no PROV_RSA_SCHANNEL support\n");
1646 ok (result
, "%08x\n", GetLastError());
1648 CryptReleaseContext(hProv
, 0);
1650 result
= CryptAcquireContext(&hProv
, NULL
, NULL
, PROV_RSA_SCHANNEL
, CRYPT_VERIFYCONTEXT
);
1651 ok (result
, "%08x\n", GetLastError());
1652 if (!result
) return;
1654 /* To get deterministic results, we import the TLS1 master secret (which
1655 * is typically generated from a random generator). Therefore, we need
1657 dwLen
= (DWORD
)sizeof(abPlainPrivateKey
);
1658 result
= CryptImportKey(hProv
, abPlainPrivateKey
, dwLen
, 0, 0, &hRSAKey
);
1659 ok (result
, "%08x\n", GetLastError());
1660 if (!result
) return;
1662 dwLen
= (DWORD
)sizeof(abTLS1Master
);
1663 result
= CryptImportKey(hProv
, abTLS1Master
, dwLen
, hRSAKey
, 0, &hMasterSecret
);
1664 ok (result
, "%08x\n", GetLastError());
1665 if (!result
) return;
1667 /* Setting the TLS1 client and server random parameters, as well as the
1668 * MAC and encryption algorithm parameters. */
1669 data_blob
.cbData
= 33;
1670 data_blob
.pbData
= abClientSecret
;
1671 result
= CryptSetKeyParam(hMasterSecret
, KP_CLIENT_RANDOM
, (BYTE
*)&data_blob
, 0);
1672 ok (result
, "%08x\n", GetLastError());
1673 if (!result
) return;
1675 data_blob
.cbData
= 33;
1676 data_blob
.pbData
= abServerSecret
;
1677 result
= CryptSetKeyParam(hMasterSecret
, KP_SERVER_RANDOM
, (BYTE
*)&data_blob
, 0);
1678 ok (result
, "%08x\n", GetLastError());
1679 if (!result
) return;
1681 saSChannelAlg
.dwUse
= SCHANNEL_ENC_KEY
;
1682 saSChannelAlg
.Algid
= CALG_DES
;
1683 saSChannelAlg
.cBits
= 64;
1684 saSChannelAlg
.dwFlags
= 0;
1685 saSChannelAlg
.dwReserved
= 0;
1686 result
= CryptSetKeyParam(hMasterSecret
, KP_SCHANNEL_ALG
, (PBYTE
)&saSChannelAlg
, 0);
1687 ok (result
, "%08x\n", GetLastError());
1688 if (!result
) return;
1690 saSChannelAlg
.dwUse
= SCHANNEL_MAC_KEY
;
1691 saSChannelAlg
.Algid
= CALG_MD5
;
1692 saSChannelAlg
.cBits
= 128;
1693 saSChannelAlg
.dwFlags
= 0;
1694 saSChannelAlg
.dwReserved
= 0;
1695 result
= CryptSetKeyParam(hMasterSecret
, KP_SCHANNEL_ALG
, (PBYTE
)&saSChannelAlg
, 0);
1696 ok (result
, "%08x\n", GetLastError());
1697 if (!result
) return;
1699 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1700 * (Keys can only be derived from hashes, not from other keys.) */
1701 result
= CryptCreateHash(hProv
, CALG_SCHANNEL_MASTER_HASH
, hMasterSecret
, 0, &hMasterHash
);
1702 ok (result
, "%08x\n", GetLastError());
1703 if (!result
) return;
1705 /* Deriving the server write encryption key from the master hash */
1706 result
= CryptDeriveKey(hProv
, CALG_SCHANNEL_ENC_KEY
, hMasterHash
, CRYPT_SERVER
, &hServerWriteKey
);
1707 ok (result
, "%08x\n", GetLastError());
1708 if (!result
) return;
1710 /* Encrypting some data with the server write encryption key and checking the result. */
1712 result
= CryptEncrypt(hServerWriteKey
, 0, TRUE
, 0, abData
, &dwLen
, 16);
1713 ok (result
&& (dwLen
== 16) && !memcmp(abData
, abEncryptedData
, 16), "%08x\n", GetLastError());
1715 /* Second test case: Test the TLS1 pseudo random number function. */
1716 result
= CryptCreateHash(hProv
, CALG_TLS1PRF
, hMasterSecret
, 0, &hTLS1PRF
);
1717 ok (result
, "%08x\n", GetLastError());
1718 if (!result
) return;
1720 /* Set the label and seed parameters for the random number function */
1721 data_blob
.cbData
= 36;
1722 data_blob
.pbData
= abHashedHandshakes
;
1723 result
= CryptSetHashParam(hTLS1PRF
, HP_TLS1PRF_SEED
, (BYTE
*)&data_blob
, 0);
1724 ok (result
, "%08x\n", GetLastError());
1725 if (!result
) return;
1727 data_blob
.cbData
= 15;
1728 data_blob
.pbData
= abClientFinished
;
1729 result
= CryptSetHashParam(hTLS1PRF
, HP_TLS1PRF_LABEL
, (BYTE
*)&data_blob
, 0);
1730 ok (result
, "%08x\n", GetLastError());
1731 if (!result
) return;
1733 /* Generate some pseudo random bytes and check if they are correct. */
1734 dwLen
= (DWORD
)sizeof(abData
);
1735 result
= CryptGetHashParam(hTLS1PRF
, HP_HASHVAL
, abData
, &dwLen
, 0);
1736 ok (result
&& (dwLen
==(DWORD
)sizeof(abData
)) && !memcmp(abData
, abPRF
, sizeof(abData
)),
1737 "%08x\n", GetLastError());
1739 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1740 * Hash some data with the HMAC. Compare results. */
1741 result
= CryptDeriveKey(hProv
, CALG_SCHANNEL_MAC_KEY
, hMasterHash
, CRYPT_SERVER
, &hServerWriteMACKey
);
1742 ok (result
, "%08x\n", GetLastError());
1743 if (!result
) return;
1745 result
= CryptCreateHash(hProv
, CALG_HMAC
, hServerWriteMACKey
, 0, &hHMAC
);
1746 ok (result
, "%08x\n", GetLastError());
1747 if (!result
) return;
1749 result
= CryptSetHashParam(hHMAC
, HP_HMAC_INFO
, (PBYTE
)&hmacInfo
, 0);
1750 ok (result
, "%08x\n", GetLastError());
1751 if (!result
) return;
1753 result
= CryptHashData(hHMAC
, abData
, (DWORD
)sizeof(abData
), 0);
1754 ok (result
, "%08x\n", GetLastError());
1755 if (!result
) return;
1757 dwLen
= (DWORD
)sizeof(abMD5Hash
);
1758 result
= CryptGetHashParam(hHMAC
, HP_HASHVAL
, abMD5Hash
, &dwLen
, 0);
1759 ok (result
&& (dwLen
== 16) && !memcmp(abMD5Hash
, abMD5
, 16), "%08x\n", GetLastError());
1761 CryptDestroyHash(hHMAC
);
1762 CryptDestroyHash(hTLS1PRF
);
1763 CryptDestroyHash(hMasterHash
);
1764 CryptDestroyKey(hServerWriteMACKey
);
1765 CryptDestroyKey(hServerWriteKey
);
1766 CryptDestroyKey(hRSAKey
);
1767 CryptDestroyKey(hMasterSecret
);
1768 CryptReleaseContext(hProv
, 0);
1769 CryptAcquireContext(&hProv
, NULL
, NULL
, PROV_RSA_SCHANNEL
, CRYPT_DELETEKEYSET
);
1772 static void test_enum_container(void)
1774 BYTE abContainerName
[MAX_PATH
+ 2]; /* Larger than maximum name len */
1776 BOOL result
, fFound
= FALSE
;
1778 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1779 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1780 result
= CryptGetProvParam(hProv
, PP_ENUMCONTAINERS
, NULL
, &dwBufferLen
, CRYPT_FIRST
);
1781 ok (result
&& dwBufferLen
== MAX_PATH
+ 1, "%08x\n", GetLastError());
1783 /* If the result fits into abContainerName dwBufferLen is left untouched */
1784 dwBufferLen
= (DWORD
)sizeof(abContainerName
);
1785 result
= CryptGetProvParam(hProv
, PP_ENUMCONTAINERS
, abContainerName
, &dwBufferLen
, CRYPT_FIRST
);
1786 ok (result
&& dwBufferLen
== (DWORD
)sizeof(abContainerName
), "%08x\n", GetLastError());
1788 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1790 if (!strcmp((const char*)abContainerName
, "winetest")) fFound
= TRUE
;
1791 dwBufferLen
= (DWORD
)sizeof(abContainerName
);
1792 } while (CryptGetProvParam(hProv
, PP_ENUMCONTAINERS
, abContainerName
, &dwBufferLen
, 0));
1794 ok (fFound
&& GetLastError() == ERROR_NO_MORE_ITEMS
, "%d, %08x\n", fFound
, GetLastError());
1797 static BYTE signBlob
[] = {
1798 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1799 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1800 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1801 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1802 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1803 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1804 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1805 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1806 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1807 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1808 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1809 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1810 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1811 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1812 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1813 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1814 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1815 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1816 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1817 0xb6,0x85,0x86,0x07 };
1819 static void test_null_provider(void)
1824 DWORD keySpec
, dataLen
,dwParam
;
1825 char szName
[MAX_PATH
];
1827 result
= CryptAcquireContext(NULL
, szContainer
, NULL
, 0, 0);
1828 ok(!result
&& GetLastError() == NTE_BAD_PROV_TYPE
,
1829 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1830 result
= CryptAcquireContext(NULL
, szContainer
, NULL
, PROV_RSA_FULL
, 0);
1831 ok(!result
&& (GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == NTE_BAD_KEYSET
),
1832 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
1833 result
= CryptAcquireContext(NULL
, szContainer
, NULL
, PROV_RSA_FULL
,
1834 CRYPT_DELETEKEYSET
);
1835 ok(!result
&& ( GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == NTE_BAD_KEYSET
),
1836 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
1837 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
1838 CRYPT_DELETEKEYSET
);
1839 ok(!result
&& GetLastError() == NTE_BAD_KEYSET
,
1840 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1841 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
, 0);
1842 ok(!result
&& GetLastError() == NTE_BAD_KEYSET
,
1843 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1845 /* Delete the default container. */
1846 CryptAcquireContext(&prov
, NULL
, NULL
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
1847 /* Once you've deleted the default container you can't open it as if it
1850 result
= CryptAcquireContext(&prov
, NULL
, NULL
, PROV_RSA_FULL
, 0);
1851 ok(!result
&& GetLastError() == NTE_BAD_KEYSET
,
1852 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1853 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1854 result
= CryptAcquireContext(&prov
, NULL
, NULL
, PROV_RSA_FULL
,
1855 CRYPT_VERIFYCONTEXT
);
1856 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
1857 if (!result
) return;
1858 dataLen
= sizeof(keySpec
);
1859 result
= CryptGetProvParam(prov
, PP_KEYSPEC
, (LPBYTE
)&keySpec
, &dataLen
, 0);
1861 ok(keySpec
== (AT_KEYEXCHANGE
| AT_SIGNATURE
),
1862 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec
);
1863 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1864 * supported, you can't get the keys from this container.
1866 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
1867 ok(!result
&& GetLastError() == NTE_NO_KEY
,
1868 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1869 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
1870 ok(!result
&& GetLastError() == NTE_NO_KEY
,
1871 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1872 result
= CryptReleaseContext(prov
, 0);
1873 ok(result
, "CryptReleaseContext failed: %08x\n", GetLastError());
1874 /* You can create a new default container. */
1875 result
= CryptAcquireContext(&prov
, NULL
, NULL
, PROV_RSA_FULL
,
1877 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
1878 /* But you still can't get the keys (until one's been generated.) */
1879 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
1880 ok(!result
&& GetLastError() == NTE_NO_KEY
,
1881 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1882 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
1883 ok(!result
&& GetLastError() == NTE_NO_KEY
,
1884 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1885 CryptReleaseContext(prov
, 0);
1886 CryptAcquireContext(&prov
, NULL
, NULL
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
1888 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
1889 CRYPT_DELETEKEYSET
);
1890 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
, 0);
1891 ok(!result
&& GetLastError() == NTE_BAD_KEYSET
,
1892 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1893 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
1894 CRYPT_VERIFYCONTEXT
);
1895 ok(!result
&& GetLastError() == NTE_BAD_FLAGS
,
1896 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1897 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
1899 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
1900 if (!result
) return;
1901 /* Test provider parameters getter */
1902 dataLen
= sizeof(dwParam
);
1903 result
= CryptGetProvParam(prov
, PP_PROVTYPE
, (LPBYTE
)&dwParam
, &dataLen
, 0);
1904 ok(result
&& dataLen
== sizeof(dwParam
) && dwParam
== PROV_RSA_FULL
,
1905 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam
);
1906 dataLen
= sizeof(dwParam
);
1907 result
= CryptGetProvParam(prov
, PP_KEYSET_TYPE
, (LPBYTE
)&dwParam
, &dataLen
, 0);
1908 ok(result
&& dataLen
== sizeof(dwParam
) && dwParam
== 0,
1909 "Expected 0, got 0x%08X\n",dwParam
);
1910 dataLen
= sizeof(dwParam
);
1911 result
= CryptGetProvParam(prov
, PP_KEYSTORAGE
, (LPBYTE
)&dwParam
, &dataLen
, 0);
1912 ok(result
&& dataLen
== sizeof(dwParam
) && (dwParam
& CRYPT_SEC_DESCR
),
1913 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam
);
1914 dataLen
= sizeof(keySpec
);
1915 SetLastError(0xdeadbeef);
1916 result
= CryptGetProvParam(prov
, PP_KEYSPEC
, (LPBYTE
)&keySpec
, &dataLen
, 0);
1917 if (!result
&& GetLastError() == NTE_BAD_TYPE
)
1918 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
1920 ok(result
&& keySpec
== (AT_KEYEXCHANGE
| AT_SIGNATURE
),
1921 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec
);
1922 /* PP_CONTAINER parameter */
1923 dataLen
= sizeof(szName
);
1924 result
= CryptGetProvParam(prov
, PP_CONTAINER
, (LPBYTE
)szName
, &dataLen
, 0);
1925 ok(result
&& dataLen
== strlen(szContainer
)+1 && strcmp(szContainer
,szName
) == 0,
1926 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1927 (result
)? "TRUE":"FALSE",GetLastError(),dataLen
);
1928 /* PP_UNIQUE_CONTAINER parameter */
1929 dataLen
= sizeof(szName
);
1930 SetLastError(0xdeadbeef);
1931 result
= CryptGetProvParam(prov
, PP_UNIQUE_CONTAINER
, (LPBYTE
)szName
, &dataLen
, 0);
1932 if (!result
&& GetLastError() == NTE_BAD_TYPE
)
1934 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
1938 char container
[MAX_PATH
];
1940 ok(result
, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
1941 uniquecontainer(container
);
1944 ok(dataLen
== strlen(container
)+1, "Expected a param length of 70, got %d\n", dataLen
);
1945 ok(!strcmp(container
, szName
), "Wrong container name : %s\n", szName
);
1948 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
1949 ok(!result
&& GetLastError() == NTE_NO_KEY
,
1950 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1951 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
1952 ok(!result
&& GetLastError() == NTE_NO_KEY
,
1953 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1955 /* Importing a key exchange blob.. */
1956 result
= CryptImportKey(prov
, abPlainPrivateKey
, sizeof(abPlainPrivateKey
),
1958 ok(result
, "CryptImportKey failed: %08x\n", GetLastError());
1959 CryptDestroyKey(key
);
1960 /* allows access to the key exchange key.. */
1961 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
1962 ok(result
, "CryptGetUserKey failed: %08x\n", GetLastError());
1963 CryptDestroyKey(key
);
1964 /* but not to the private key. */
1965 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
1966 ok(!result
&& GetLastError() == NTE_NO_KEY
,
1967 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1968 CryptReleaseContext(prov
, 0);
1969 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
1970 CRYPT_DELETEKEYSET
);
1972 /* Whereas importing a sign blob.. */
1973 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
1975 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
1976 if (!result
) return;
1977 result
= CryptImportKey(prov
, signBlob
, sizeof(signBlob
), 0, 0, &key
);
1978 ok(result
, "CryptGenKey failed: %08x\n", GetLastError());
1979 CryptDestroyKey(key
);
1980 /* doesn't allow access to the key exchange key.. */
1981 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
1982 ok(!result
&& GetLastError() == NTE_NO_KEY
,
1983 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1984 /* but does to the private key. */
1985 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
1986 ok(result
, "CryptGetUserKey failed: %08x\n", GetLastError());
1987 CryptDestroyKey(key
);
1988 CryptReleaseContext(prov
, 0);
1990 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
1991 CRYPT_DELETEKEYSET
);
1994 /* test for the bug in accessing the user key in a container
1996 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
1998 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
1999 result
= CryptGenKey(prov
, AT_KEYEXCHANGE
, 0, &key
);
2000 ok(result
, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2001 CryptDestroyKey(key
);
2002 CryptReleaseContext(prov
,0);
2003 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,0);
2004 ok(result
, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2005 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2006 ok (result
, "CryptGetUserKey failed with error %08x\n", GetLastError());
2007 CryptDestroyKey(key
);
2008 CryptReleaseContext(prov
, 0);
2010 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2011 CRYPT_DELETEKEYSET
);
2013 /* test the machine key set */
2014 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2015 CRYPT_DELETEKEYSET
|CRYPT_MACHINE_KEYSET
);
2016 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2017 CRYPT_NEWKEYSET
|CRYPT_MACHINE_KEYSET
);
2018 ok(result
, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2019 CryptReleaseContext(prov
, 0);
2020 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2021 CRYPT_MACHINE_KEYSET
);
2022 ok(result
, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2023 CryptReleaseContext(prov
,0);
2024 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2025 CRYPT_DELETEKEYSET
|CRYPT_MACHINE_KEYSET
);
2026 ok(result
, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2028 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2029 CRYPT_MACHINE_KEYSET
);
2030 ok(!result
&& GetLastError() == NTE_BAD_KEYSET
,
2031 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2037 if (!init_base_environment())
2049 test_block_cipher_modes();
2050 test_import_private();
2051 test_verify_signature();
2053 test_import_export();
2054 test_enum_container();
2055 clean_up_base_environment();
2056 test_schannel_provider();
2057 test_null_provider();
2058 if (!init_aes_environment())
2063 clean_up_aes_environment();