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(DWORD dwKeyFlags
)
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
, 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
);
145 static void clean_up_base_environment(void)
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)
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");
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
,
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
);
202 static void clean_up_aes_environment(void)
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)
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");
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");
231 ok(result
&& dwInc
==8, "%08x, %d\n", GetLastError(), dwInc
);
234 static void test_gen_random(void)
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 */
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
)
260 unsigned char pbData
[2000];
264 for (i
=0; i
<2000; i
++) pbData
[i
] = (unsigned char)i
;
265 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
267 /* rsaenh compiled without OpenSSL */
268 ok(GetLastError()==NTE_BAD_ALGID
, "%08x\n", GetLastError());
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
;
280 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbData
, &len
, 0);
281 ok(result
, "%08x\n", GetLastError());
282 CryptDestroyHash(hHash
);
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];
305 HCRYPTHASH hHash
, hHashClone
;
306 BYTE pbHashValue
[36];
310 for (i
=0; i
<2048; i
++) pbData
[i
] = (unsigned char)i
;
313 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
315 /* rsaenh compiled without OpenSSL */
316 ok(GetLastError() == NTE_BAD_ALGID
, "%08x\n", GetLastError());
318 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
319 ok(result
, "%08x\n", GetLastError());
322 result
= CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
323 ok(result
&& (hashlen
== 16), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
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());
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());
343 result
= CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
344 ok(result
&& (hashlen
== 16), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
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());
356 result
= CryptCreateHash(hProv
, CALG_MD5
, 0, 0, &hHash
);
357 ok(result
, "%08x\n", GetLastError());
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());
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 */
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());
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());
423 result
= CryptGetHashParam(hHashClone
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
424 ok(result
&& (hashlen
== 20), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
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 };
459 result
= derive_key(CALG_RC2
, &hKey
, 40);
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());
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
);
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());
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
);
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());
506 result
= CryptEncrypt(hKey
, 0, FALSE
, 0, abData
, &dwLen
, 24);
507 ok(result
&& dwLen
== 16, "%08x, dwLen: %d\n", GetLastError(), dwLen
);
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
);
515 result
= CryptDecrypt(hKey
, 0, FALSE
, 0, abData
, &dwLen
);
516 ok(result
&& dwLen
== 8, "%08x, dwLen: %d\n", GetLastError(), dwLen
);
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());
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)
539 unsigned char pbData
[16];
542 result
= derive_key(CALG_3DES_112
, &hKey
, 0);
544 /* rsaenh compiled without OpenSSL */
545 ok(GetLastError() == NTE_BAD_ALGID
, "%08x\n", GetLastError());
549 for (i
=0; i
<sizeof(pbData
); i
++) pbData
[i
] = (unsigned char)i
;
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());
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)
587 unsigned char pbData
[16];
590 result
= derive_key(CALG_DES
, &hKey
, 56);
592 /* rsaenh compiled without OpenSSL */
593 ok(GetLastError()==NTE_BAD_ALGID
, "%08x\n", GetLastError());
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
;
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());
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)
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 };
650 result
= derive_key(CALG_3DES
, &hKey
, 0);
653 for (i
=0; i
<sizeof(pbData
); i
++) pbData
[i
] = (unsigned char)i
;
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());
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
)
693 unsigned char pbData
[16];
699 result
= derive_key(CALG_AES_256
, &hKey
, 0);
702 result
= derive_key(CALG_AES_192
, &hKey
, 0);
706 result
= derive_key(CALG_AES_128
, &hKey
, 0);
711 for (i
=0; i
<sizeof(pbData
); i
++) pbData
[i
] = (unsigned char)i
;
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());
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,
755 DWORD dwLen
, dwKeyLen
, dwDataLen
, dwMode
, dwModeBits
;
757 unsigned char pbData
[2000], pbHashValue
[16];
760 for (i
=0; i
<2000; i
++) pbData
[i
] = (unsigned char)i
;
763 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
765 ok(GetLastError()==NTE_BAD_ALGID
, "%08x\n", GetLastError());
767 CRYPT_INTEGER_BLOB salt
;
769 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
770 ok(result
, "%08x\n", GetLastError());
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());
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());
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
;
847 result
= CryptSetKeyParam(hKey
, KP_SALT_EX
, (BYTE
*)&salt
, 0);
848 ok(result
, "setting salt failed for size %d: %08x\n", i
, GetLastError());
851 SetLastError(0xdeadbeef);
852 result
= CryptSetKeyParam(hKey
, KP_SALT_EX
, (BYTE
*)&salt
, 0);
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
);
866 ok(GetLastError()==NTE_BAD_ALGID
, "%08x\n", GetLastError());
868 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
869 ok(result
, "%08x\n", GetLastError());
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());
882 SetLastError(0xdeadbeef);
883 result
= CryptSetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (LPBYTE
)&dwKeyLen
, 0);
884 ok(!result
&& GetLastError()==NTE_BAD_DATA
, "%08x\n", GetLastError());
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());
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());
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 */
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 };
933 DWORD dwDataLen
= 5, dwKeyLen
, dwLen
= sizeof(DWORD
), dwMode
;
934 unsigned char pbData
[2000], *pbTemp
;
935 unsigned char pszBuffer
[256];
938 for (i
=0; i
<2000; i
++) pbData
[i
] = (unsigned char)i
;
941 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
943 /* rsaenh compiled without OpenSSL */
944 ok(GetLastError() == NTE_BAD_ALGID
, "%08x\n", GetLastError());
946 CRYPT_INTEGER_BLOB salt
;
948 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
949 ok(result
, "%08x\n", GetLastError());
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());
985 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, NULL
, &dwDataLen
, 24);
986 ok(result
, "%08x\n", GetLastError());
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
;
1001 result
= CryptSetKeyParam(hKey
, KP_SALT_EX
, (BYTE
*)&salt
, 0);
1002 ok(result
, "setting salt failed for size %d: %08x\n", i
, GetLastError());
1005 SetLastError(0xdeadbeef);
1006 result
= CryptSetKeyParam(hKey
, KP_SALT_EX
, (BYTE
*)&salt
, 0);
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) {
1020 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1021 HMAC_INFO hmacInfo
= { CALG_MD5
, NULL
, 0, NULL
, 0 };
1024 static const BYTE hmac
[16] = {
1025 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1026 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
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) {
1065 BYTE abData
[256], abEnc
[264];
1066 static const BYTE mac_40
[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
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;
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)
1191 HCRYPTKEY hKeyExchangeKey
, hSessionKey
;
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
);
1221 /* rsaenh compiled without OpenSSL */
1222 ok(GetLastError() == NTE_FAIL
, "%08x\n", GetLastError());
1226 dwLen
= (DWORD
)sizeof(abSessionKey
);
1227 result
= CryptImportKey(hProv
, abSessionKey
, dwLen
, hKeyExchangeKey
, 0, &hSessionKey
);
1228 ok(result
, "%08x\n", GetLastError());
1229 if (!result
) return;
1232 dwLen
= sizeof(DWORD
);
1233 result
= CryptGetKeyParam(hSessionKey
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwLen
, 0);
1234 ok(result
, "%08x\n", GetLastError());
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) {
1266 HCRYPTKEY hPubSignKey
;
1267 BYTE abData
[] = "Wine rocks!";
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());
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)
1543 BYTE abData
[2048] = "Wine rocks!";
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;
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
);
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());
1565 dwLen
= sizeof(DWORD
);
1566 result
= CryptGetKeyParam(hRSAKey
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwLen
, 0);
1567 ok(result
, "%08x\n", GetLastError());
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);
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;
1599 dwLen
= sizeof(DWORD
);
1600 result
= CryptGetKeyParam(hRSAKey
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwLen
, 0);
1601 ok(result
, "%08x\n", GetLastError());
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);
1622 (GetLastError() == NTE_BAD_DATA
|| GetLastError() == NTE_BAD_FLAGS
),
1623 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
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
;
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
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
);
1663 dwDataLen
= sizeof(DWORD
);
1664 result
= CryptGetKeyParam(hPublicKey
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwDataLen
, 0);
1665 ok(result
, "%08x\n", GetLastError());
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)
1682 HCRYPTKEY hRSAKey
, hMasterSecret
, hServerWriteKey
, hServerWriteMACKey
;
1683 HCRYPTHASH hMasterHash
, hTLS1PRF
, hHMAC
;
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!";
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
);
1731 win_skip("no PROV_RSA_SCHANNEL support\n");
1734 ok (result
, "%08x\n", GetLastError());
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
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. */
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 */
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. */
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)
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
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);
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
,
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
,
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");
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");
2030 char container
[MAX_PATH
];
2032 ok(result
, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2033 uniquecontainer(container
);
2036 ok(dataLen
== strlen(container
)+1, "Expected a param length of 70, got %d\n", dataLen
);
2037 ok(!strcmp(container
, szName
), "Wrong container name : %s\n", szName
);
2040 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2041 ok(!result
&& GetLastError() == NTE_NO_KEY
,
2042 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2043 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
2044 ok(!result
&& GetLastError() == NTE_NO_KEY
,
2045 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2047 /* Importing a key exchange blob.. */
2048 result
= CryptImportKey(prov
, abPlainPrivateKey
, sizeof(abPlainPrivateKey
),
2050 ok(result
, "CryptImportKey failed: %08x\n", GetLastError());
2051 CryptDestroyKey(key
);
2052 /* allows access to the key exchange key.. */
2053 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2054 ok(result
, "CryptGetUserKey failed: %08x\n", GetLastError());
2055 CryptDestroyKey(key
);
2056 /* but not to the private key. */
2057 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
2058 ok(!result
&& GetLastError() == NTE_NO_KEY
,
2059 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2060 CryptReleaseContext(prov
, 0);
2061 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2062 CRYPT_DELETEKEYSET
);
2064 /* Whereas importing a sign blob.. */
2065 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2067 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
2068 if (!result
) return;
2069 result
= CryptImportKey(prov
, signBlob
, sizeof(signBlob
), 0, 0, &key
);
2070 ok(result
, "CryptGenKey failed: %08x\n", GetLastError());
2071 CryptDestroyKey(key
);
2072 /* doesn't allow access to the key exchange key.. */
2073 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2074 ok(!result
&& GetLastError() == NTE_NO_KEY
,
2075 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2076 /* but does to the private key. */
2077 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
2078 ok(result
, "CryptGetUserKey failed: %08x\n", GetLastError());
2079 CryptDestroyKey(key
);
2080 CryptReleaseContext(prov
, 0);
2082 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2083 CRYPT_DELETEKEYSET
);
2086 /* test for the bug in accessing the user key in a container
2088 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2090 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
2091 result
= CryptGenKey(prov
, AT_KEYEXCHANGE
, 0, &key
);
2092 ok(result
, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2093 CryptDestroyKey(key
);
2094 CryptReleaseContext(prov
,0);
2095 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,0);
2096 ok(result
, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2097 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2098 ok (result
, "CryptGetUserKey failed with error %08x\n", GetLastError());
2099 CryptDestroyKey(key
);
2100 CryptReleaseContext(prov
, 0);
2102 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2103 CRYPT_DELETEKEYSET
);
2105 /* test the machine key set */
2106 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2107 CRYPT_DELETEKEYSET
|CRYPT_MACHINE_KEYSET
);
2108 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2109 CRYPT_NEWKEYSET
|CRYPT_MACHINE_KEYSET
);
2110 ok(result
, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2111 CryptReleaseContext(prov
, 0);
2112 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2113 CRYPT_MACHINE_KEYSET
);
2114 ok(result
, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2115 CryptReleaseContext(prov
,0);
2116 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2117 CRYPT_DELETEKEYSET
|CRYPT_MACHINE_KEYSET
);
2118 ok(result
, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2120 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2121 CRYPT_MACHINE_KEYSET
);
2122 ok(!result
&& GetLastError() == NTE_BAD_KEYSET
,
2123 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2127 static void test_key_permissions(void)
2129 HCRYPTKEY hKey1
, hKey2
;
2133 /* Create keys that are exportable */
2134 if (!init_base_environment(CRYPT_EXPORTABLE
))
2137 result
= CryptGetUserKey(hProv
, AT_KEYEXCHANGE
, &hKey1
);
2138 ok (result
, "%08x\n", GetLastError());
2139 if (!result
) return;
2142 dwLen
= sizeof(DWORD
);
2143 result
= CryptGetKeyParam(hKey1
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwLen
, 0);
2144 ok(result
, "%08x\n", GetLastError());
2146 (CRYPT_MAC
|CRYPT_WRITE
|CRYPT_READ
|CRYPT_EXPORT
|CRYPT_DECRYPT
|CRYPT_ENCRYPT
) ||
2147 broken(dwVal
== 0xffffffff), /* Win9x/NT4 */
2148 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2149 " got %08x\n", dwVal
);
2151 /* The key exchange key's public key may be exported.. */
2152 result
= CryptExportKey(hKey1
, 0, PUBLICKEYBLOB
, 0, NULL
, &dwLen
);
2153 ok(result
, "%08x\n", GetLastError());
2154 /* and its private key may be too. */
2155 result
= CryptExportKey(hKey1
, 0, PRIVATEKEYBLOB
, 0, NULL
, &dwLen
);
2156 ok(result
, "%08x\n", GetLastError());
2157 /* Turning off the key's export permissions is "allowed".. */
2158 dwVal
&= ~CRYPT_EXPORT
;
2159 result
= CryptSetKeyParam(hKey1
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, 0);
2161 broken(!result
&& GetLastError() == NTE_BAD_DATA
) || /* W2K */
2162 broken(!result
&& GetLastError() == NTE_BAD_FLAGS
), /* Win9x/WinME/NT4 */
2163 "%08x\n", GetLastError());
2164 /* but it has no effect. */
2166 dwLen
= sizeof(DWORD
);
2167 result
= CryptGetKeyParam(hKey1
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwLen
, 0);
2168 ok(result
, "%08x\n", GetLastError());
2170 (CRYPT_MAC
|CRYPT_WRITE
|CRYPT_READ
|CRYPT_EXPORT
|CRYPT_DECRYPT
|CRYPT_ENCRYPT
) ||
2171 broken(dwVal
== 0xffffffff), /* Win9x/NT4 */
2172 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2173 " got %08x\n", dwVal
);
2174 /* Thus, changing the export flag of the key doesn't affect whether the key
2177 result
= CryptExportKey(hKey1
, 0, PRIVATEKEYBLOB
, 0, NULL
, &dwLen
);
2178 ok(result
, "%08x\n", GetLastError());
2180 result
= CryptGetUserKey(hProv
, AT_KEYEXCHANGE
, &hKey2
);
2181 ok (result
, "%08x\n", GetLastError());
2183 /* A subsequent get of the same key, into a different handle, also doesn't
2184 * show that the permissions have been changed.
2187 dwLen
= sizeof(DWORD
);
2188 result
= CryptGetKeyParam(hKey2
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwLen
, 0);
2189 ok(result
, "%08x\n", GetLastError());
2191 (CRYPT_MAC
|CRYPT_WRITE
|CRYPT_READ
|CRYPT_EXPORT
|CRYPT_DECRYPT
|CRYPT_ENCRYPT
) ||
2192 broken(dwVal
== 0xffffffff), /* Win9x/NT4 */
2193 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2194 " got %08x\n", dwVal
);
2196 CryptDestroyKey(hKey2
);
2197 CryptDestroyKey(hKey1
);
2199 clean_up_base_environment();
2202 static void test_key_initialization(void)
2205 HCRYPTPROV prov1
, prov2
;
2206 HCRYPTKEY hKeyExchangeKey
, hSessionKey
, hKey
;
2208 static BYTE abSessionKey
[148] = {
2209 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2210 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2211 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2212 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2213 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2214 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2215 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2216 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2217 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2218 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2219 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2220 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2221 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2222 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2223 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2224 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2225 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2226 0x04, 0x8c, 0x49, 0x92
2229 /* Like init_base_environment, but doesn't generate new keys, as they'll
2230 * be imported instead.
2232 if (!CryptAcquireContext(&prov1
, szContainer
, szProvider
, PROV_RSA_FULL
, 0))
2234 result
= CryptAcquireContext(&prov1
, szContainer
, szProvider
, PROV_RSA_FULL
,
2236 ok(result
, "%08x\n", GetLastError());
2238 dwLen
= (DWORD
)sizeof(abPlainPrivateKey
);
2239 result
= CryptImportKey(prov1
, abPlainPrivateKey
, dwLen
, 0, 0, &hKeyExchangeKey
);
2241 dwLen
= (DWORD
)sizeof(abSessionKey
);
2242 result
= CryptImportKey(prov1
, abSessionKey
, dwLen
, hKeyExchangeKey
, 0, &hSessionKey
);
2243 ok(result
, "%08x\n", GetLastError());
2245 /* Once the key has been imported, subsequently acquiring a context with
2246 * the same name will allow retrieving the key.
2248 result
= CryptAcquireContext(&prov2
, szContainer
, szProvider
, PROV_RSA_FULL
, 0);
2249 ok(result
, "%08x\n", GetLastError());
2250 result
= CryptGetUserKey(prov2
, AT_KEYEXCHANGE
, &hKey
);
2251 ok(result
, "%08x\n", GetLastError());
2252 if (result
) CryptDestroyKey(hKey
);
2253 CryptReleaseContext(prov2
, 0);
2255 CryptDestroyKey(hSessionKey
);
2256 CryptDestroyKey(hKeyExchangeKey
);
2257 CryptReleaseContext(prov1
, 0);
2258 CryptAcquireContext(&prov1
, szContainer
, NULL
, PROV_RSA_FULL
,
2259 CRYPT_DELETEKEYSET
);
2264 if (!init_base_environment(0))
2276 test_block_cipher_modes();
2277 test_import_private();
2278 test_verify_signature();
2280 test_import_export();
2281 test_enum_container();
2282 clean_up_base_environment();
2283 test_key_permissions();
2284 test_key_initialization();
2285 test_schannel_provider();
2286 test_null_provider();
2287 if (!init_aes_environment())
2292 clean_up_aes_environment();