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
;
77 /* Get the MachineGUID */
78 ret
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
, szCryptography
, 0, KEY_READ
| KEY_WOW64_64KEY
, &hkey
);
79 if (ret
== ERROR_ACCESS_DENIED
)
81 /* Windows 2000 can't handle KEY_WOW64_64KEY */
82 RegOpenKeyA(HKEY_LOCAL_MACHINE
, szCryptography
, &hkey
);
84 RegQueryValueExA(hkey
, szMachineGuid
, NULL
, NULL
, (LPBYTE
)guid
, &size
);
87 lstrcpy(unique
, szContainer_md5
);
89 lstrcat(unique
, guid
);
92 static void printBytes(const char *heading
, const BYTE
*pb
, size_t cb
)
95 printf("%s: ",heading
);
97 printf("0x%02x,",pb
[i
]);
101 static BOOL (WINAPI
*pCryptDuplicateHash
) (HCRYPTHASH
, DWORD
*, DWORD
, HCRYPTHASH
*);
104 static void trace_hex(BYTE *pbData, DWORD dwLen) {
108 for (i = 0; i < dwLen-7; i+=8) {
109 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
110 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
111 pbData[i+6], pbData[i+7]);
114 for (j=0; i<dwLen; j++,i++) {
115 sprintf(szTemp+6*j, "0x%02x,\n", pbData[i]);
121 static int init_base_environment(DWORD dwKeyFlags
)
126 pCryptDuplicateHash
= (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
128 hProv
= (HCRYPTPROV
)INVALID_HANDLE_VALUE
;
130 result
= CryptAcquireContext(&hProv
, szContainer
, szProvider
, PROV_RSA_FULL
, CRYPT_VERIFYCONTEXT
);
131 ok(!result
&& (GetLastError()==NTE_BAD_FLAGS
||
132 broken(GetLastError() == NTE_KEYSET_NOT_DEF
/* Win9x/NT4 */)),
133 "%d, %08x\n", result
, GetLastError());
135 if (!CryptAcquireContext(&hProv
, szContainer
, szProvider
, PROV_RSA_FULL
, 0))
137 ok(GetLastError()==NTE_BAD_KEYSET
||
138 broken(GetLastError() == NTE_TEMPORARY_PROFILE
/* some Win7 setups */) ||
139 broken(GetLastError() == NTE_KEYSET_NOT_DEF
/* Win9x/NT4 */),
140 "%08x\n", GetLastError());
141 if (GetLastError()!=NTE_BAD_KEYSET
)
143 win_skip("RSA full provider not available\n");
146 result
= CryptAcquireContext(&hProv
, szContainer
, szProvider
, PROV_RSA_FULL
,
148 ok(result
, "%08x\n", GetLastError());
151 win_skip("Couldn't create crypto provider\n");
154 result
= CryptGenKey(hProv
, AT_KEYEXCHANGE
, dwKeyFlags
, &hKey
);
155 ok(result
, "%08x\n", GetLastError());
156 if (result
) CryptDestroyKey(hKey
);
157 result
= CryptGenKey(hProv
, AT_SIGNATURE
, dwKeyFlags
, &hKey
);
158 ok(result
, "%08x\n", GetLastError());
159 if (result
) CryptDestroyKey(hKey
);
164 static void clean_up_base_environment(void)
168 SetLastError(0xdeadbeef);
169 result
= CryptReleaseContext(hProv
, 1);
170 ok(!result
|| broken(result
) /* Win98 */, "Expected failure\n");
171 ok(GetLastError()==NTE_BAD_FLAGS
, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
173 /* Just to prove that Win98 also released the CSP */
174 SetLastError(0xdeadbeef);
175 result
= CryptReleaseContext(hProv
, 0);
176 ok(!result
&& GetLastError()==ERROR_INVALID_PARAMETER
, "%08x\n", GetLastError());
178 CryptAcquireContext(&hProv
, szContainer
, szProvider
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
181 static int init_aes_environment(void)
186 pCryptDuplicateHash
= (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
188 hProv
= (HCRYPTPROV
)INVALID_HANDLE_VALUE
;
190 /* we are using NULL as provider name for RSA_AES provider as the provider
191 * names are different in Windows XP and Vista. Its different as to what
192 * its defined in the SDK on Windows XP.
193 * This provider is available on Windows XP, Windows 2003 and Vista. */
195 result
= CryptAcquireContext(&hProv
, szContainer
, NULL
, PROV_RSA_AES
, CRYPT_VERIFYCONTEXT
);
196 if (!result
&& GetLastError() == NTE_PROV_TYPE_NOT_DEF
)
198 win_skip("RSA_AES provider not supported\n");
201 ok(!result
&& GetLastError()==NTE_BAD_FLAGS
, "%d, %08x\n", result
, GetLastError());
203 if (!CryptAcquireContext(&hProv
, szContainer
, NULL
, PROV_RSA_AES
, 0))
205 ok(GetLastError()==NTE_BAD_KEYSET
, "%08x\n", GetLastError());
206 if (GetLastError()!=NTE_BAD_KEYSET
) return 0;
207 result
= CryptAcquireContext(&hProv
, szContainer
, NULL
, PROV_RSA_AES
,
209 ok(result
, "%08x\n", GetLastError());
210 if (!result
) return 0;
211 result
= CryptGenKey(hProv
, AT_KEYEXCHANGE
, 0, &hKey
);
212 ok(result
, "%08x\n", GetLastError());
213 if (result
) CryptDestroyKey(hKey
);
214 result
= CryptGenKey(hProv
, AT_SIGNATURE
, 0, &hKey
);
215 ok(result
, "%08x\n", GetLastError());
216 if (result
) CryptDestroyKey(hKey
);
221 static void clean_up_aes_environment(void)
225 result
= CryptReleaseContext(hProv
, 1);
226 ok(!result
&& GetLastError()==NTE_BAD_FLAGS
, "%08x\n", GetLastError());
228 CryptAcquireContext(&hProv
, szContainer
, NULL
, PROV_RSA_AES
, CRYPT_DELETEKEYSET
);
231 static void test_prov(void)
236 dwLen
= (DWORD
)sizeof(DWORD
);
237 SetLastError(0xdeadbeef);
238 result
= CryptGetProvParam(hProv
, PP_SIG_KEYSIZE_INC
, (BYTE
*)&dwInc
, &dwLen
, 0);
239 if (!result
&& GetLastError() == NTE_BAD_TYPE
)
240 skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
242 ok(result
&& dwInc
==8, "%08x, %d\n", GetLastError(), dwInc
);
244 dwLen
= (DWORD
)sizeof(DWORD
);
245 SetLastError(0xdeadbeef);
246 result
= CryptGetProvParam(hProv
, PP_KEYX_KEYSIZE_INC
, (BYTE
*)&dwInc
, &dwLen
, 0);
247 if (!result
&& GetLastError() == NTE_BAD_TYPE
)
248 skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
250 ok(result
&& dwInc
==8, "%08x, %d\n", GetLastError(), dwInc
);
253 static void test_gen_random(void)
256 BYTE rnd1
[16], rnd2
[16];
258 memset(rnd1
, 0, sizeof(rnd1
));
259 memset(rnd2
, 0, sizeof(rnd2
));
261 result
= CryptGenRandom(hProv
, sizeof(rnd1
), rnd1
);
262 if (!result
&& GetLastError() == NTE_FAIL
) {
263 /* rsaenh compiled without OpenSSL */
267 ok(result
, "%08x\n", GetLastError());
269 result
= CryptGenRandom(hProv
, sizeof(rnd2
), rnd2
);
270 ok(result
, "%08x\n", GetLastError());
272 ok(memcmp(rnd1
, rnd2
, sizeof(rnd1
)), "CryptGenRandom generates non random data\n");
275 static BOOL
derive_key(ALG_ID aiAlgid
, HCRYPTKEY
*phKey
, DWORD len
)
279 unsigned char pbData
[2000];
283 for (i
=0; i
<2000; i
++) pbData
[i
] = (unsigned char)i
;
284 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
286 /* rsaenh compiled without OpenSSL */
287 ok(GetLastError()==NTE_BAD_ALGID
, "%08x\n", GetLastError());
290 ok(result
, "%08x\n", GetLastError());
291 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
292 ok(result
, "%08x\n", GetLastError());
293 if (!result
) return FALSE
;
294 result
= CryptDeriveKey(hProv
, aiAlgid
, hHash
, (len
<< 16) | CRYPT_EXPORTABLE
, phKey
);
295 ok(result
, "%08x\n", GetLastError());
296 if (!result
) return FALSE
;
298 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbData
, &len
, 0);
299 ok(result
, "%08x\n", GetLastError());
300 CryptDestroyHash(hHash
);
304 static BYTE abPlainPrivateKey
[596] = {
305 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
306 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
307 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
308 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
309 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
310 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
311 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
312 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
313 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
314 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
315 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
316 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
317 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
318 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
319 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
320 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
321 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
322 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
323 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
324 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
325 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
326 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
327 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
328 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
329 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
330 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
331 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
332 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
333 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
334 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
335 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
336 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
337 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
338 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
339 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
340 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
341 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
342 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
343 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
344 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
345 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
346 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
347 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
348 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
349 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
350 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
351 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
352 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
353 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
354 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
355 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
356 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
357 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
358 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
359 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
360 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
361 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
362 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
363 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
364 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
365 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
366 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
367 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
368 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
369 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
370 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
371 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
372 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
373 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
374 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
375 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
376 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
377 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
378 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
379 0xf2, 0x5d, 0x58, 0x07
382 static void test_hashes(void)
384 static const unsigned char md2hash
[16] = {
385 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
386 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
387 static const unsigned char md4hash
[16] = {
388 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
389 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
390 static const unsigned char empty_md5hash
[16] = {
391 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
392 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
393 static const unsigned char md5hash
[16] = {
394 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
395 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
396 static const unsigned char sha1hash
[20] = {
397 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
398 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
399 static const unsigned char signed_ssl3_shamd5_hash
[] = {
400 0x4f,0xcc,0x2f,0x33,0x44,0x60,0x76,0x16,0x13,0xc8,0xff,0xd4,0x59,0x19,
401 0xde,0x85,0x44,0x72,0x47,0x98,0x01,0xfb,0x67,0x5c,0x5b,0x35,0x15,0x0f,
402 0x91,0xda,0xc7,0x7c,0xfb,0xe2,0x18,0xef,0xac,0x31,0x40,0x7b,0xa9,0x83,
403 0xdb,0x30,0xcd,0x94,0x4b,0x8e,0x3b,0x6c,0x7a,0x86,0x59,0xf0,0xd1,0xd2,
404 0x5e,0xce,0xd4,0x1b,0x7f,0xed,0x24,0xee,0x53,0x5c,0x15,0x97,0x21,0x7c,
405 0x5c,0xea,0xab,0xf5,0xd6,0x4b,0xb3,0xbb,0x14,0xf5,0x59,0x9e,0x21,0x90,
406 0x21,0x99,0x19,0xad,0xa2,0xa6,0xea,0x61,0xc1,0x41,0xe2,0x70,0x77,0xf7,
407 0x15,0x68,0x96,0x1e,0x5c,0x84,0x97,0xe3,0x5c,0xd2,0xd9,0xfb,0x87,0x6f,
408 0x11,0x21,0x82,0x43,0x76,0x32,0xa4,0x38,0x7b,0x85,0x22,0x30,0x1e,0x55,
410 unsigned char pbData
[2048];
412 HCRYPTHASH hHash
, hHashClone
;
414 BYTE pbHashValue
[36];
415 BYTE pbSigValue
[128];
416 HCRYPTKEY hKeyExchangeKey
;
417 DWORD hashlen
, len
, error
;
420 for (i
=0; i
<2048; i
++) pbData
[i
] = (unsigned char)i
;
423 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
425 /* rsaenh compiled without OpenSSL */
426 ok(GetLastError() == NTE_BAD_ALGID
, "%08x\n", GetLastError());
428 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
429 ok(result
, "%08x\n", GetLastError());
432 result
= CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
433 ok(result
&& (hashlen
== 16), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
436 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
437 ok(result
, "%08x\n", GetLastError());
439 ok(!memcmp(pbHashValue
, md2hash
, 16), "Wrong MD2 hash!\n");
441 result
= CryptDestroyHash(hHash
);
442 ok(result
, "%08x\n", GetLastError());
446 result
= CryptCreateHash(hProv
, CALG_MD4
, 0, 0, &hHash
);
447 ok(result
, "%08x\n", GetLastError());
449 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
450 ok(result
, "%08x\n", GetLastError());
453 result
= CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
454 ok(result
&& (hashlen
== 16), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
457 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
458 ok(result
, "%08x\n", GetLastError());
460 ok(!memcmp(pbHashValue
, md4hash
, 16), "Wrong MD4 hash!\n");
462 result
= CryptDestroyHash(hHash
);
463 ok(result
, "%08x\n", GetLastError());
466 result
= CryptCreateHash(hProv
, CALG_MD5
, 0, 0, &hHash
);
467 ok(result
, "%08x\n", GetLastError());
470 result
= CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
471 ok(result
&& (hashlen
== 16), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
473 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
474 ok(result
, "%08x\n", GetLastError());
477 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
478 ok(result
, "%08x\n", GetLastError());
480 ok(!memcmp(pbHashValue
, md5hash
, 16), "Wrong MD5 hash!\n");
482 result
= CryptDestroyHash(hHash
);
483 ok(result
, "%08x\n", GetLastError());
485 result
= CryptCreateHash(hProv
, CALG_MD5
, 0, 0, &hHash
);
486 ok(result
, "%08x\n", GetLastError());
488 /* The hash is available even if CryptHashData hasn't been called */
490 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
491 ok(result
, "%08x\n", GetLastError());
493 ok(!memcmp(pbHashValue
, empty_md5hash
, 16), "Wrong MD5 hash!\n");
495 /* It's also stable: getting it twice results in the same value */
496 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
497 ok(result
, "%08x\n", GetLastError());
499 ok(!memcmp(pbHashValue
, empty_md5hash
, 16), "Wrong MD5 hash!\n");
501 /* Can't add data after the hash been retrieved */
502 SetLastError(0xdeadbeef);
503 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
504 ok(!result
, "Expected failure\n");
505 ok(GetLastError() == NTE_BAD_HASH_STATE
||
506 GetLastError() == NTE_BAD_ALGID
, /* Win9x, WinMe, NT4 */
507 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
509 /* You can still retrieve the hash, its value just hasn't changed */
510 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
511 ok(result
, "%08x\n", GetLastError());
513 ok(!memcmp(pbHashValue
, empty_md5hash
, 16), "Wrong MD5 hash!\n");
515 result
= CryptDestroyHash(hHash
);
516 ok(result
, "%08x\n", GetLastError());
519 result
= CryptCreateHash(hProv
, CALG_SHA
, 0, 0, &hHash
);
520 ok(result
, "%08x\n", GetLastError());
522 result
= CryptHashData(hHash
, pbData
, 5, 0);
523 ok(result
, "%08x\n", GetLastError());
525 if(pCryptDuplicateHash
) {
526 result
= pCryptDuplicateHash(hHash
, 0, 0, &hHashClone
);
527 ok(result
, "%08x\n", GetLastError());
529 result
= CryptHashData(hHashClone
, (BYTE
*)pbData
+5, sizeof(pbData
)-5, 0);
530 ok(result
, "%08x\n", GetLastError());
533 result
= CryptGetHashParam(hHashClone
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
534 ok(result
&& (hashlen
== 20), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
537 result
= CryptGetHashParam(hHashClone
, HP_HASHVAL
, pbHashValue
, &len
, 0);
538 ok(result
, "%08x\n", GetLastError());
540 ok(!memcmp(pbHashValue
, sha1hash
, 20), "Wrong SHA1 hash!\n");
542 result
= CryptDestroyHash(hHashClone
);
543 ok(result
, "%08x\n", GetLastError());
546 result
= CryptDestroyHash(hHash
);
547 ok(result
, "%08x\n", GetLastError());
549 /* The SHA-2 variants aren't supported in the RSA full provider */
550 result
= CryptCreateHash(hProv
, CALG_SHA_256
, 0, 0, &hHash
);
551 ok(!result
&& GetLastError() == NTE_BAD_ALGID
,
552 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
553 result
= CryptCreateHash(hProv
, CALG_SHA_384
, 0, 0, &hHash
);
554 ok(!result
&& GetLastError() == NTE_BAD_ALGID
,
555 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
556 result
= CryptCreateHash(hProv
, CALG_SHA_512
, 0, 0, &hHash
);
557 ok(!result
&& GetLastError() == NTE_BAD_ALGID
,
558 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
560 result
= CryptAcquireContextA(&prov
, NULL
, szProvider
, PROV_RSA_FULL
, CRYPT_VERIFYCONTEXT
);
561 ok(result
, "CryptAcquireContext failed 0x%08x\n", GetLastError());
563 result
= CryptCreateHash(prov
, CALG_SHA1
, 0, 0, &hHash
);
564 ok(result
, "CryptCreateHash failed 0x%08x\n", GetLastError());
566 /* release provider before using the hash */
567 result
= CryptReleaseContext(prov
, 0);
568 ok(result
, "CryptReleaseContext failed 0x%08x\n", GetLastError());
570 SetLastError(0xdeadbeef);
571 result
= CryptHashData(hHash
, (const BYTE
*)"data", sizeof("data"), 0);
572 error
= GetLastError();
573 ok(!result
, "CryptHashData succeeded\n");
574 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER got %u\n", error
);
576 SetLastError(0xdeadbeef);
577 result
= CryptDestroyHash(hHash
);
578 error
= GetLastError();
579 ok(!result
, "CryptDestroyHash succeeded\n");
580 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER got %u\n", error
);
582 if (!pCryptDuplicateHash
)
584 win_skip("CryptDuplicateHash is not available\n");
588 result
= CryptAcquireContextA(&prov
, NULL
, szProvider
, PROV_RSA_FULL
, CRYPT_VERIFYCONTEXT
);
589 ok(result
, "CryptAcquireContext failed 0x%08x\n", GetLastError());
591 result
= CryptCreateHash(hProv
, CALG_SHA1
, 0, 0, &hHash
);
592 ok(result
, "CryptCreateHash failed 0x%08x\n", GetLastError());
594 result
= CryptHashData(hHash
, (const BYTE
*)"data", sizeof("data"), 0);
595 ok(result
, "CryptHashData failed 0x%08x\n", GetLastError());
597 result
= pCryptDuplicateHash(hHash
, NULL
, 0, &hHashClone
);
598 ok(result
, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
601 result
= CryptGetHashParam(hHashClone
, HP_HASHVAL
, pbHashValue
, &len
, 0);
602 ok(result
, "CryptGetHashParam failed 0x%08x\n", GetLastError());
604 /* add data after duplicating the hash */
605 result
= CryptHashData(hHash
, (const BYTE
*)"more data", sizeof("more data"), 0);
606 ok(result
, "CryptHashData failed 0x%08x\n", GetLastError());
608 result
= CryptDestroyHash(hHash
);
609 ok(result
, "CryptDestroyHash failed 0x%08x\n", GetLastError());
611 result
= CryptDestroyHash(hHashClone
);
612 ok(result
, "CryptDestroyHash failed 0x%08x\n", GetLastError());
614 result
= CryptReleaseContext(prov
, 0);
615 ok(result
, "CryptReleaseContext failed 0x%08x\n", GetLastError());
617 /* Test CALG_SSL3_SHAMD5 */
618 result
= CryptAcquireContextA(&prov
, NULL
, szProvider
, PROV_RSA_FULL
, CRYPT_VERIFYCONTEXT
);
619 ok(result
, "CryptAcquireContext failed 0x%08x\n", GetLastError());
621 /* Step 1: create an MD5 hash of the data */
622 result
= CryptCreateHash(hProv
, CALG_MD5
, 0, 0, &hHash
);
623 ok(result
, "CryptCreateHash failed 0x%08x\n", GetLastError());
624 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
625 ok(result
, "%08x\n", GetLastError());
627 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
628 ok(result
, "CryptGetHashParam failed 0x%08x\n", GetLastError());
629 result
= CryptDestroyHash(hHash
);
630 ok(result
, "CryptDestroyHash failed 0x%08x\n", GetLastError());
631 /* Step 2: create a SHA1 hash of the data */
632 result
= CryptCreateHash(hProv
, CALG_SHA
, 0, 0, &hHash
);
633 ok(result
, "CryptCreateHash failed 0x%08x\n", GetLastError());
634 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
635 ok(result
, "%08x\n", GetLastError());
637 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
+ 16, &len
, 0);
638 ok(result
, "CryptGetHashParam failed 0x%08x\n", GetLastError());
639 result
= CryptDestroyHash(hHash
);
640 ok(result
, "CryptDestroyHash failed 0x%08x\n", GetLastError());
641 /* Step 3: create a CALG_SSL3_SHAMD5 hash handle */
642 result
= CryptCreateHash(hProv
, CALG_SSL3_SHAMD5
, 0, 0, &hHash
);
643 ok(result
, "CryptCreateHash failed 0x%08x\n", GetLastError());
644 /* Test that CryptHashData fails on this hash */
645 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
646 ok(!result
&& GetLastError() == NTE_BAD_ALGID
, "%08x\n", GetLastError());
647 result
= CryptSetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, 0);
648 ok(result
, "%08x\n", GetLastError());
649 len
= (DWORD
)sizeof(abPlainPrivateKey
);
650 result
= CryptImportKey(hProv
, abPlainPrivateKey
, len
, 0, 0, &hKeyExchangeKey
);
651 ok(result
, "%08x\n", GetLastError());
653 result
= CryptSignHash(hHash
, AT_KEYEXCHANGE
, NULL
, 0, NULL
, &len
);
654 ok(result
, "%08x\n", GetLastError());
655 ok(len
== 128, "expected len 128, got %d\n", len
);
656 result
= CryptSignHash(hHash
, AT_KEYEXCHANGE
, NULL
, 0, pbSigValue
, &len
);
657 ok(result
, "%08x\n", GetLastError());
658 ok(!memcmp(pbSigValue
, signed_ssl3_shamd5_hash
, len
), "unexpected value\n");
659 if (len
!= 128 || memcmp(pbSigValue
, signed_ssl3_shamd5_hash
, len
))
661 printBytes("expected", signed_ssl3_shamd5_hash
,
662 sizeof(signed_ssl3_shamd5_hash
));
663 printBytes("got", pbSigValue
, len
);
665 result
= CryptDestroyKey(hKeyExchangeKey
);
666 ok(result
, "CryptDestroyKey failed 0x%08x\n", GetLastError());
667 result
= CryptDestroyHash(hHash
);
668 ok(result
, "CryptDestroyHash failed 0x%08x\n", GetLastError());
669 result
= CryptReleaseContext(prov
, 0);
670 ok(result
, "CryptReleaseContext failed 0x%08x\n", GetLastError());
673 static void test_block_cipher_modes(void)
675 static const BYTE plain
[23] = {
676 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
677 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
678 static const BYTE ecb
[24] = {
679 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
680 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
681 static const BYTE cbc
[24] = {
682 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
683 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
684 static const BYTE cfb
[24] = {
685 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
686 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
692 result
= derive_key(CALG_RC2
, &hKey
, 40);
695 memcpy(abData
, plain
, sizeof(plain
));
697 dwMode
= CRYPT_MODE_ECB
;
698 result
= CryptSetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, 0);
699 ok(result
, "%08x\n", GetLastError());
701 result
= CryptGetKeyParam(hKey
, KP_SALT
, NULL
, &dwLen
, 0);
702 ok(result
, "%08x\n", GetLastError());
703 ok(dwLen
== 11 || broken(dwLen
== 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen
);
706 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, NULL
, &dwLen
, 24);
707 ok(result
, "CryptEncrypt failed: %08x\n", GetLastError());
708 ok(dwLen
== 24, "Unexpected length %d\n", dwLen
);
710 SetLastError(ERROR_SUCCESS
);
712 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, abData
, &dwLen
, 24);
713 ok(result
&& dwLen
== 24 && !memcmp(ecb
, abData
, sizeof(ecb
)),
714 "%08x, dwLen: %d\n", GetLastError(), dwLen
);
716 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, abData
, &dwLen
);
717 ok(result
&& dwLen
== 23 && !memcmp(plain
, abData
, sizeof(plain
)),
718 "%08x, dwLen: %d\n", GetLastError(), dwLen
);
720 dwMode
= CRYPT_MODE_CBC
;
721 result
= CryptSetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, 0);
722 ok(result
, "%08x\n", GetLastError());
725 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, NULL
, &dwLen
, 24);
726 ok(result
, "CryptEncrypt failed: %08x\n", GetLastError());
727 ok(dwLen
== 24, "Unexpected length %d\n", dwLen
);
730 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, abData
, &dwLen
, 24);
731 ok(result
&& dwLen
== 24 && !memcmp(cbc
, abData
, sizeof(cbc
)),
732 "%08x, dwLen: %d\n", GetLastError(), dwLen
);
734 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, abData
, &dwLen
);
735 ok(result
&& dwLen
== 23 && !memcmp(plain
, abData
, sizeof(plain
)),
736 "%08x, dwLen: %d\n", GetLastError(), dwLen
);
738 dwMode
= CRYPT_MODE_CFB
;
739 result
= CryptSetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, 0);
740 ok(result
, "%08x\n", GetLastError());
743 result
= CryptEncrypt(hKey
, 0, FALSE
, 0, abData
, &dwLen
, 24);
744 ok(result
&& dwLen
== 16, "%08x, dwLen: %d\n", GetLastError(), dwLen
);
747 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, abData
+16, &dwLen
, 8);
748 ok(result
&& dwLen
== 8 && !memcmp(cfb
, abData
, sizeof(cfb
)),
749 "%08x, dwLen: %d\n", GetLastError(), dwLen
);
752 result
= CryptDecrypt(hKey
, 0, FALSE
, 0, abData
, &dwLen
);
753 ok(result
&& dwLen
== 8, "%08x, dwLen: %d\n", GetLastError(), dwLen
);
756 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, abData
+8, &dwLen
);
757 ok(result
&& dwLen
== 15 && !memcmp(plain
, abData
, sizeof(plain
)),
758 "%08x, dwLen: %d\n", GetLastError(), dwLen
);
760 dwMode
= CRYPT_MODE_OFB
;
761 result
= CryptSetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, 0);
762 ok(result
, "%08x\n", GetLastError());
765 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, abData
, &dwLen
, 24);
766 ok(!result
&& GetLastError() == NTE_BAD_ALGID
, "%08x\n", GetLastError());
768 CryptDestroyKey(hKey
);
771 static void test_3des112(void)
776 unsigned char pbData
[16], enc_data
[16], bad_data
[16];
779 result
= derive_key(CALG_3DES_112
, &hKey
, 0);
781 /* rsaenh compiled without OpenSSL */
782 ok(GetLastError() == NTE_BAD_ALGID
, "%08x\n", GetLastError());
786 for (i
=0; i
<sizeof(pbData
); i
++) pbData
[i
] = (unsigned char)i
;
789 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, 16);
790 ok(result
, "%08x\n", GetLastError());
792 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
793 ok(result
, "%08x\n", GetLastError());
797 memcpy(pbData
,cTestData
[i
].origstr
,cTestData
[i
].strlen
);
799 dwLen
= cTestData
[i
].enclen
;
800 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, cTestData
[i
].buflen
);
801 ok(result
, "%08x\n", GetLastError());
802 ok(dwLen
==cTestData
[i
].buflen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].buflen
);
803 memcpy(enc_data
, pbData
, cTestData
[i
].buflen
);
805 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
806 ok(result
, "%08x\n", GetLastError());
807 ok(dwLen
==cTestData
[i
].enclen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].enclen
);
808 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[1].enclen
)==0,"decryption incorrect %d\n",i
);
809 if((dwLen
!= cTestData
[i
].enclen
) ||
810 memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
))
812 printBytes("expected",cTestData
[i
].decstr
,cTestData
[i
].strlen
);
813 printBytes("got",pbData
,dwLen
);
817 Decrypting a block of bad data with Final = TRUE should restore the
818 initial state of the key as well as decrypting a block of good data.
821 /* Changing key state by setting Final = FALSE */
822 dwLen
= cTestData
[i
].buflen
;
823 memcpy(pbData
, enc_data
, cTestData
[i
].buflen
);
824 result
= CryptDecrypt(hKey
, 0, FALSE
, 0, pbData
, &dwLen
);
825 ok(result
, "%08x\n", GetLastError());
827 /* Restoring key state by decrypting bad_data with Final = TRUE */
828 memcpy(bad_data
, enc_data
, cTestData
[i
].buflen
);
829 bad_data
[cTestData
[i
].buflen
- 1] = ~bad_data
[cTestData
[i
].buflen
- 1];
830 SetLastError(0xdeadbeef);
831 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, bad_data
, &dwLen
);
832 ok(!result
, "CryptDecrypt should failed!\n");
833 ok(GetLastError() == NTE_BAD_DATA
, "%08x\n", GetLastError());
834 ok(dwLen
==cTestData
[i
].buflen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].buflen
);
835 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[1].enclen
)==0,"decryption incorrect %d\n",i
);
837 /* Checking key state */
838 dwLen
= cTestData
[i
].buflen
;
839 memcpy(pbData
, enc_data
, cTestData
[i
].buflen
);
840 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
841 ok(result
, "%08x\n", GetLastError());
842 ok(dwLen
==cTestData
[i
].enclen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].enclen
);
843 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[1].enclen
)==0,"decryption incorrect %d\n",i
);
844 if((dwLen
!= cTestData
[i
].enclen
) ||
845 memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
))
847 printBytes("expected",cTestData
[i
].decstr
,cTestData
[i
].strlen
);
848 printBytes("got",pbData
,dwLen
);
851 result
= CryptDestroyKey(hKey
);
852 ok(result
, "%08x\n", GetLastError());
855 static void test_des(void)
860 unsigned char pbData
[16], enc_data
[16], bad_data
[16];
863 result
= derive_key(CALG_DES
, &hKey
, 56);
865 /* rsaenh compiled without OpenSSL */
866 ok(GetLastError()==NTE_BAD_ALGID
, "%08x\n", GetLastError());
870 dwMode
= CRYPT_MODE_ECB
;
871 result
= CryptSetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, 0);
872 ok(result
, "%08x\n", GetLastError());
874 dwLen
= sizeof(DWORD
);
875 result
= CryptGetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, &dwLen
, 0);
876 ok(result
, "%08x\n", GetLastError());
878 for (i
=0; i
<sizeof(pbData
); i
++) pbData
[i
] = (unsigned char)i
;
881 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, 16);
882 ok(result
, "%08x\n", GetLastError());
884 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
885 ok(result
, "%08x\n", GetLastError());
889 memcpy(pbData
,cTestData
[i
].origstr
,cTestData
[i
].strlen
);
891 dwLen
= cTestData
[i
].enclen
;
892 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, cTestData
[i
].buflen
);
893 ok(result
, "%08x\n", GetLastError());
894 ok(dwLen
==cTestData
[i
].buflen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].buflen
);
895 memcpy(enc_data
, pbData
, cTestData
[i
].buflen
);
897 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
898 ok(result
, "%08x\n", GetLastError());
899 ok(dwLen
==cTestData
[i
].enclen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].enclen
);
900 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
)==0,"decryption incorrect %d\n",i
);
901 if((dwLen
!= cTestData
[i
].enclen
) ||
902 memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
))
904 printBytes("expected",cTestData
[i
].decstr
,cTestData
[i
].strlen
);
905 printBytes("got",pbData
,dwLen
);
909 Decrypting a block of bad data with Final = TRUE should restore the
910 initial state of the key as well as decrypting a block of good data.
913 /* Changing key state by setting Final = FALSE */
914 dwLen
= cTestData
[i
].buflen
;
915 memcpy(pbData
, enc_data
, cTestData
[i
].buflen
);
916 result
= CryptDecrypt(hKey
, 0, FALSE
, 0, pbData
, &dwLen
);
917 ok(result
, "%08x\n", GetLastError());
919 /* Restoring key state by decrypting bad_data with Final = TRUE */
920 memcpy(bad_data
, enc_data
, cTestData
[i
].buflen
);
921 bad_data
[cTestData
[i
].buflen
- 1] = ~bad_data
[cTestData
[i
].buflen
- 1];
922 SetLastError(0xdeadbeef);
923 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, bad_data
, &dwLen
);
924 ok(!result
, "CryptDecrypt should failed!\n");
925 ok(GetLastError() == NTE_BAD_DATA
, "%08x\n", GetLastError());
926 ok(dwLen
==cTestData
[i
].buflen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].buflen
);
927 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[1].enclen
)==0,"decryption incorrect %d\n",i
);
929 /* Checking key state */
930 dwLen
= cTestData
[i
].buflen
;
931 memcpy(pbData
, enc_data
, cTestData
[i
].buflen
);
932 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
933 ok(result
, "%08x\n", GetLastError());
934 ok(dwLen
==cTestData
[i
].enclen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].enclen
);
935 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[1].enclen
)==0,"decryption incorrect %d\n",i
);
936 if((dwLen
!= cTestData
[i
].enclen
) ||
937 memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
))
939 printBytes("expected",cTestData
[i
].decstr
,cTestData
[i
].strlen
);
940 printBytes("got",pbData
,dwLen
);
944 result
= CryptDestroyKey(hKey
);
945 ok(result
, "%08x\n", GetLastError());
948 static void test_3des(void)
953 unsigned char pbData
[16], enc_data
[16], bad_data
[16];
954 static const BYTE des3
[16] = {
955 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
956 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
959 result
= derive_key(CALG_3DES
, &hKey
, 0);
962 for (i
=0; i
<sizeof(pbData
); i
++) pbData
[i
] = (unsigned char)i
;
965 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, 16);
966 ok(result
, "%08x\n", GetLastError());
968 ok(!memcmp(pbData
, des3
, sizeof(des3
)), "3DES encryption failed!\n");
970 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
971 ok(result
, "%08x\n", GetLastError());
975 memcpy(pbData
,cTestData
[i
].origstr
,cTestData
[i
].strlen
);
977 dwLen
= cTestData
[i
].enclen
;
978 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, cTestData
[i
].buflen
);
979 ok(result
, "%08x\n", GetLastError());
980 ok(dwLen
==cTestData
[i
].buflen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].buflen
);
981 memcpy(enc_data
, pbData
, cTestData
[i
].buflen
);
983 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
984 ok(result
, "%08x\n", GetLastError());
985 ok(dwLen
==cTestData
[i
].enclen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].enclen
);
986 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
)==0,"decryption incorrect %d\n",i
);
987 if((dwLen
!= cTestData
[i
].enclen
) ||
988 memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
))
990 printBytes("expected",cTestData
[i
].decstr
,cTestData
[i
].strlen
);
991 printBytes("got",pbData
,dwLen
);
995 Decrypting a block of bad data with Final = TRUE should restore the
996 initial state of the key as well as decrypting a block of good data.
999 /* Changing key state by setting Final = FALSE */
1000 dwLen
= cTestData
[i
].buflen
;
1001 memcpy(pbData
, enc_data
, cTestData
[i
].buflen
);
1002 result
= CryptDecrypt(hKey
, 0, FALSE
, 0, pbData
, &dwLen
);
1003 ok(result
, "%08x\n", GetLastError());
1005 /* Restoring key state by decrypting bad_data with Final = TRUE */
1006 memcpy(bad_data
, enc_data
, cTestData
[i
].buflen
);
1007 bad_data
[cTestData
[i
].buflen
- 1] = ~bad_data
[cTestData
[i
].buflen
- 1];
1008 SetLastError(0xdeadbeef);
1009 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, bad_data
, &dwLen
);
1010 ok(!result
, "CryptDecrypt should failed!\n");
1011 ok(GetLastError() == NTE_BAD_DATA
, "%08x\n", GetLastError());
1012 ok(dwLen
==cTestData
[i
].buflen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].buflen
);
1013 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[1].enclen
)==0,"decryption incorrect %d\n",i
);
1015 /* Checking key state */
1016 dwLen
= cTestData
[i
].buflen
;
1017 memcpy(pbData
, enc_data
, cTestData
[i
].buflen
);
1018 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
1019 ok(result
, "%08x\n", GetLastError());
1020 ok(dwLen
==cTestData
[i
].enclen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].enclen
);
1021 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[1].enclen
)==0,"decryption incorrect %d\n",i
);
1022 if((dwLen
!= cTestData
[i
].enclen
) ||
1023 memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
))
1025 printBytes("expected",cTestData
[i
].decstr
,cTestData
[i
].strlen
);
1026 printBytes("got",pbData
,dwLen
);
1029 result
= CryptDestroyKey(hKey
);
1030 ok(result
, "%08x\n", GetLastError());
1033 static void test_aes(int keylen
)
1038 unsigned char pbData
[16], enc_data
[16], bad_data
[16];
1044 result
= derive_key(CALG_AES_256
, &hKey
, 0);
1047 result
= derive_key(CALG_AES_192
, &hKey
, 0);
1051 result
= derive_key(CALG_AES_128
, &hKey
, 0);
1054 if (!result
) return;
1056 for (i
=0; i
<sizeof(pbData
); i
++) pbData
[i
] = (unsigned char)i
;
1058 /* Does AES provider support salt? */
1059 result
= CryptGetKeyParam(hKey
, KP_SALT
, NULL
, &dwLen
, 0);
1060 ok((!result
&& GetLastError() == NTE_BAD_KEY
) || result
/* Win7 */,
1061 "expected NTE_BAD_KEY, got %08x\n", GetLastError());
1063 ok(!dwLen
, "unexpected salt length %d\n", dwLen
);
1066 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, 16);
1067 ok(result
, "%08x\n", GetLastError());
1069 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
1070 ok(result
, "%08x\n", GetLastError());
1074 memcpy(pbData
,cTestData
[i
].origstr
,cTestData
[i
].strlen
);
1076 dwLen
= cTestData
[i
].enclen
;
1077 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
, cTestData
[i
].buflen
);
1078 ok(result
, "%08x\n", GetLastError());
1079 ok(dwLen
==cTestData
[i
].buflen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].buflen
);
1080 memcpy(enc_data
, pbData
, cTestData
[i
].buflen
);
1082 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
1083 ok(result
, "%08x\n", GetLastError());
1084 ok(dwLen
==cTestData
[i
].enclen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].enclen
);
1085 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[1].enclen
)==0,"decryption incorrect %d\n",i
);
1086 if((dwLen
!= cTestData
[i
].enclen
) ||
1087 memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
))
1089 printBytes("expected",cTestData
[i
].decstr
,cTestData
[i
].strlen
);
1090 printBytes("got",pbData
,dwLen
);
1094 Decrypting a block of bad data with Final = TRUE should restore the
1095 initial state of the key as well as decrypting a block of good data.
1098 /* Changing key state by setting Final = FALSE */
1099 dwLen
= cTestData
[i
].buflen
;
1100 memcpy(pbData
, enc_data
, cTestData
[i
].buflen
);
1101 result
= CryptDecrypt(hKey
, 0, FALSE
, 0, pbData
, &dwLen
);
1102 ok(result
, "%08x\n", GetLastError());
1104 /* Restoring key state by decrypting bad_data with Final = TRUE */
1105 memcpy(bad_data
, enc_data
, cTestData
[i
].buflen
);
1106 bad_data
[cTestData
[i
].buflen
- 1] = ~bad_data
[cTestData
[i
].buflen
- 1];
1107 SetLastError(0xdeadbeef);
1108 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, bad_data
, &dwLen
);
1109 ok(!result
, "CryptDecrypt should failed!\n");
1110 ok(GetLastError() == NTE_BAD_DATA
, "%08x\n", GetLastError());
1111 ok(dwLen
==cTestData
[i
].buflen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].buflen
);
1112 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[1].enclen
)==0,"decryption incorrect %d\n",i
);
1114 /* Checking key state */
1115 dwLen
= cTestData
[i
].buflen
;
1116 memcpy(pbData
, enc_data
, cTestData
[i
].buflen
);
1117 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwLen
);
1118 ok(result
, "%08x\n", GetLastError());
1119 ok(dwLen
==cTestData
[i
].enclen
,"length incorrect, got %d, expected %d\n",dwLen
,cTestData
[i
].enclen
);
1120 ok(memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[1].enclen
)==0,"decryption incorrect %d\n",i
);
1121 if((dwLen
!= cTestData
[i
].enclen
) ||
1122 memcmp(pbData
,cTestData
[i
].decstr
,cTestData
[i
].enclen
))
1124 printBytes("expected",cTestData
[i
].decstr
,cTestData
[i
].strlen
);
1125 printBytes("got",pbData
,dwLen
);
1128 result
= CryptDestroyKey(hKey
);
1129 ok(result
, "%08x\n", GetLastError());
1132 static void test_sha2(void)
1134 static const unsigned char sha256hash
[32] = {
1135 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
1136 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
1137 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
1140 static const unsigned char sha384hash
[48] = {
1141 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
1142 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
1143 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
1144 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
1145 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
1147 static const unsigned char sha512hash
[64] = {
1148 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1149 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1150 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1151 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1152 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1153 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1154 0xb7, 0xf4, 0x81, 0xd4
1156 unsigned char pbData
[2048];
1159 BYTE pbHashValue
[64];
1163 for (i
=0; i
<2048; i
++) pbData
[i
] = (unsigned char)i
;
1166 SetLastError(0xdeadbeef);
1167 result
= CryptCreateHash(hProv
, CALG_SHA_256
, 0, 0, &hHash
);
1168 if (!result
&& GetLastError() == NTE_BAD_ALGID
) {
1169 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1172 ok(result
, "%08x\n", GetLastError());
1174 len
= sizeof(DWORD
);
1175 result
= CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
1176 ok(result
&& (hashlen
== 32), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
1178 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
1179 ok(result
, "%08x\n", GetLastError());
1182 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
1183 ok(result
, "%08x\n", GetLastError());
1185 ok(!memcmp(pbHashValue
, sha256hash
, 32), "Wrong SHA-256 hash!\n");
1187 result
= CryptDestroyHash(hHash
);
1188 ok(result
, "%08x\n", GetLastError());
1192 result
= CryptCreateHash(hProv
, CALG_SHA_384
, 0, 0, &hHash
);
1193 ok(result
, "%08x\n", GetLastError());
1195 len
= sizeof(DWORD
);
1196 result
= CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
1197 ok(result
&& (hashlen
== 48), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
1199 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
1200 ok(result
, "%08x\n", GetLastError());
1203 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
1204 ok(result
, "%08x\n", GetLastError());
1206 ok(!memcmp(pbHashValue
, sha384hash
, 48), "Wrong SHA-384 hash!\n");
1208 result
= CryptDestroyHash(hHash
);
1209 ok(result
, "%08x\n", GetLastError());
1213 result
= CryptCreateHash(hProv
, CALG_SHA_512
, 0, 0, &hHash
);
1214 ok(result
, "%08x\n", GetLastError());
1216 len
= sizeof(DWORD
);
1217 result
= CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashlen
, &len
, 0);
1218 ok(result
&& (hashlen
== 64), "%08x, hashlen: %d\n", GetLastError(), hashlen
);
1220 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
1221 ok(result
, "%08x\n", GetLastError());
1224 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &len
, 0);
1225 ok(result
, "%08x\n", GetLastError());
1227 ok(!memcmp(pbHashValue
, sha512hash
, 64), "Wrong SHA-512 hash!\n");
1229 result
= CryptDestroyHash(hHash
);
1230 ok(result
, "%08x\n", GetLastError());
1234 static void test_rc2(void)
1236 static const BYTE rc2_40_encrypted
[16] = {
1237 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1238 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1239 static const BYTE rc2_128_encrypted
[] = {
1240 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
1245 DWORD dwLen
, dwKeyLen
, dwDataLen
, dwMode
, dwModeBits
;
1247 unsigned char pbData
[2000], pbHashValue
[16];
1250 for (i
=0; i
<2000; i
++) pbData
[i
] = (unsigned char)i
;
1253 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
1255 ok(GetLastError()==NTE_BAD_ALGID
, "%08x\n", GetLastError());
1257 CRYPT_INTEGER_BLOB salt
;
1259 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
1260 ok(result
, "%08x\n", GetLastError());
1263 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &dwLen
, 0);
1264 ok(result
, "%08x\n", GetLastError());
1266 result
= CryptDeriveKey(hProv
, CALG_RC2
, hHash
, 40 << 16, &hKey
);
1267 ok(result
, "%08x\n", GetLastError());
1269 dwLen
= sizeof(DWORD
);
1270 result
= CryptGetKeyParam(hKey
, KP_KEYLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
1271 ok(result
, "%08x\n", GetLastError());
1273 dwMode
= CRYPT_MODE_CBC
;
1274 result
= CryptSetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, 0);
1275 ok(result
, "%08x\n", GetLastError());
1277 dwLen
= sizeof(DWORD
);
1278 result
= CryptGetKeyParam(hKey
, KP_MODE_BITS
, (BYTE
*)&dwModeBits
, &dwLen
, 0);
1279 ok(result
, "%08x\n", GetLastError());
1281 dwModeBits
= 0xdeadbeef;
1282 dwLen
= sizeof(DWORD
);
1283 result
= CryptGetKeyParam(hKey
, KP_PERMISSIONS
, (BYTE
*)&dwModeBits
, &dwLen
, 0);
1284 ok(result
, "%08x\n", GetLastError());
1286 (CRYPT_MAC
|CRYPT_WRITE
|CRYPT_READ
|CRYPT_DECRYPT
|CRYPT_ENCRYPT
) ||
1287 broken(dwModeBits
== 0xffffffff), /* Win9x/NT4 */
1288 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1289 " got %08x\n", dwModeBits
);
1291 dwLen
= sizeof(DWORD
);
1292 result
= CryptGetKeyParam(hKey
, KP_PERMISSIONS
, (BYTE
*)&dwModeBits
, &dwLen
, 0);
1293 ok(result
, "%08x\n", GetLastError());
1295 dwLen
= sizeof(DWORD
);
1296 result
= CryptGetKeyParam(hKey
, KP_BLOCKLEN
, (BYTE
*)&dwModeBits
, &dwLen
, 0);
1297 ok(result
, "%08x\n", GetLastError());
1299 result
= CryptGetKeyParam(hKey
, KP_IV
, NULL
, &dwLen
, 0);
1300 ok(result
, "%08x\n", GetLastError());
1301 pbTemp
= HeapAlloc(GetProcessHeap(), 0, dwLen
);
1302 CryptGetKeyParam(hKey
, KP_IV
, pbTemp
, &dwLen
, 0);
1303 HeapFree(GetProcessHeap(), 0, pbTemp
);
1305 result
= CryptGetKeyParam(hKey
, KP_SALT
, NULL
, &dwLen
, 0);
1306 ok(result
, "%08x\n", GetLastError());
1307 /* The default salt length is always 11... */
1308 ok(dwLen
== 11, "unexpected salt length %d\n", dwLen
);
1309 /* and the default salt is always empty. */
1310 pbTemp
= HeapAlloc(GetProcessHeap(), 0, dwLen
);
1311 CryptGetKeyParam(hKey
, KP_SALT
, pbTemp
, &dwLen
, 0);
1312 for (i
=0; i
<dwLen
; i
++)
1313 ok(!pbTemp
[i
], "unexpected salt value %02x @ %d\n", pbTemp
[i
], i
);
1314 HeapFree(GetProcessHeap(), 0, pbTemp
);
1316 dwLen
= sizeof(DWORD
);
1317 CryptGetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, &dwLen
, 0);
1319 result
= CryptDestroyHash(hHash
);
1320 ok(result
, "%08x\n", GetLastError());
1323 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwDataLen
, 24);
1324 ok(result
, "%08x\n", GetLastError());
1326 ok(!memcmp(pbData
, rc2_40_encrypted
, 16), "RC2 encryption failed!\n");
1328 result
= CryptGetKeyParam(hKey
, KP_IV
, NULL
, &dwLen
, 0);
1329 ok(result
, "%08x\n", GetLastError());
1330 pbTemp
= HeapAlloc(GetProcessHeap(), 0, dwLen
);
1331 CryptGetKeyParam(hKey
, KP_IV
, pbTemp
, &dwLen
, 0);
1332 HeapFree(GetProcessHeap(), 0, pbTemp
);
1334 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwDataLen
);
1335 ok(result
, "%08x\n", GetLastError());
1337 /* Setting the salt also succeeds... */
1338 result
= CryptSetKeyParam(hKey
, KP_SALT
, pbData
, 0);
1339 ok(result
, "setting salt failed: %08x\n", GetLastError());
1340 /* but the resulting salt length is now zero? */
1342 result
= CryptGetKeyParam(hKey
, KP_SALT
, NULL
, &dwLen
, 0);
1343 ok(result
, "%08x\n", GetLastError());
1345 broken(dwLen
== 11), /* Win9x/WinMe/NT4 */
1346 "unexpected salt length %d\n", dwLen
);
1347 /* What sizes salt can I set? */
1348 salt
.pbData
= pbData
;
1349 for (i
=0; i
<24; i
++)
1352 result
= CryptSetKeyParam(hKey
, KP_SALT_EX
, (BYTE
*)&salt
, 0);
1353 ok(result
, "setting salt failed for size %d: %08x\n", i
, GetLastError());
1354 /* The returned salt length is the same as the set salt length */
1355 result
= CryptGetKeyParam(hKey
, KP_SALT
, NULL
, &dwLen
, 0);
1356 ok(result
, "%08x\n", GetLastError());
1357 ok(dwLen
== i
, "size %d: unexpected salt length %d\n", i
, dwLen
);
1360 SetLastError(0xdeadbeef);
1361 result
= CryptSetKeyParam(hKey
, KP_SALT_EX
, (BYTE
*)&salt
, 0);
1363 broken(result
), /* Win9x, WinMe, NT4, W2K */
1364 "%08x\n", GetLastError());
1366 result
= CryptDestroyKey(hKey
);
1367 ok(result
, "%08x\n", GetLastError());
1370 /* Again, but test setting the effective key len */
1371 for (i
=0; i
<2000; i
++) pbData
[i
] = (unsigned char)i
;
1373 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
1375 ok(GetLastError()==NTE_BAD_ALGID
, "%08x\n", GetLastError());
1377 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
1378 ok(result
, "%08x\n", GetLastError());
1381 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbHashValue
, &dwLen
, 0);
1382 ok(result
, "%08x\n", GetLastError());
1384 result
= CryptDeriveKey(hProv
, CALG_RC2
, hHash
, 56 << 16, &hKey
);
1385 ok(result
, "%08x\n", GetLastError());
1387 SetLastError(0xdeadbeef);
1388 result
= CryptSetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, NULL
, 0);
1389 ok(!result
&& GetLastError()==ERROR_INVALID_PARAMETER
, "%08x\n", GetLastError());
1391 SetLastError(0xdeadbeef);
1392 result
= CryptSetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (LPBYTE
)&dwKeyLen
, 0);
1393 ok(!result
&& GetLastError()==NTE_BAD_DATA
, "%08x\n", GetLastError());
1395 SetLastError(0xdeadbeef);
1396 result
= CryptSetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (LPBYTE
)&dwKeyLen
, 0);
1397 ok(!result
, "CryptSetKeyParam failed: %08x\n", GetLastError());
1399 dwLen
= sizeof(dwKeyLen
);
1400 CryptGetKeyParam(hKey
, KP_KEYLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
1401 ok(dwKeyLen
== 56, "%d (%08x)\n", dwKeyLen
, GetLastError());
1402 CryptGetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
1403 ok(dwKeyLen
== 56 || broken(dwKeyLen
== 40), "%d (%08x)\n", dwKeyLen
, GetLastError());
1406 result
= CryptSetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (LPBYTE
)&dwKeyLen
, 0);
1407 ok(result
, "%d\n", GetLastError());
1409 dwLen
= sizeof(dwKeyLen
);
1410 CryptGetKeyParam(hKey
, KP_KEYLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
1411 ok(dwKeyLen
== 56, "%d (%08x)\n", dwKeyLen
, GetLastError());
1412 CryptGetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
1413 ok(dwKeyLen
== 128, "%d (%08x)\n", dwKeyLen
, GetLastError());
1415 result
= CryptDestroyHash(hHash
);
1416 ok(result
, "%08x\n", GetLastError());
1419 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwDataLen
, 24);
1420 ok(result
, "%08x\n", GetLastError());
1422 ok(!memcmp(pbData
, rc2_128_encrypted
, sizeof(rc2_128_encrypted
)),
1423 "RC2 encryption failed!\n");
1425 /* Oddly enough this succeeds, though it should have no effect */
1427 result
= CryptSetKeyParam(hKey
, KP_EFFECTIVE_KEYLEN
, (LPBYTE
)&dwKeyLen
, 0);
1428 ok(result
, "%d\n", GetLastError());
1430 result
= CryptDestroyKey(hKey
);
1431 ok(result
, "%08x\n", GetLastError());
1435 static void test_rc4(void)
1437 static const BYTE rc4
[16] = {
1438 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1439 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1443 DWORD dwDataLen
= 5, dwKeyLen
, dwLen
= sizeof(DWORD
), dwMode
;
1444 unsigned char pbData
[2000], *pbTemp
;
1445 unsigned char pszBuffer
[256];
1448 for (i
=0; i
<2000; i
++) pbData
[i
] = (unsigned char)i
;
1451 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
1453 /* rsaenh compiled without OpenSSL */
1454 ok(GetLastError() == NTE_BAD_ALGID
, "%08x\n", GetLastError());
1456 CRYPT_INTEGER_BLOB salt
;
1458 result
= CryptHashData(hHash
, pbData
, sizeof(pbData
), 0);
1459 ok(result
, "%08x\n", GetLastError());
1462 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, pszBuffer
, &dwLen
, 0);
1463 ok(result
, "%08x\n", GetLastError());
1465 result
= CryptDeriveKey(hProv
, CALG_RC4
, hHash
, 56 << 16, &hKey
);
1466 ok(result
, "%08x\n", GetLastError());
1468 dwLen
= sizeof(DWORD
);
1469 result
= CryptGetKeyParam(hKey
, KP_KEYLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
1470 ok(result
, "%08x\n", GetLastError());
1472 dwLen
= sizeof(DWORD
);
1473 result
= CryptGetKeyParam(hKey
, KP_BLOCKLEN
, (BYTE
*)&dwKeyLen
, &dwLen
, 0);
1474 ok(result
, "%08x\n", GetLastError());
1476 result
= CryptGetKeyParam(hKey
, KP_IV
, NULL
, &dwLen
, 0);
1477 ok(result
, "%08x\n", GetLastError());
1478 pbTemp
= HeapAlloc(GetProcessHeap(), 0, dwLen
);
1479 CryptGetKeyParam(hKey
, KP_IV
, pbTemp
, &dwLen
, 0);
1480 HeapFree(GetProcessHeap(), 0, pbTemp
);
1482 result
= CryptGetKeyParam(hKey
, KP_SALT
, NULL
, &dwLen
, 0);
1483 ok(result
, "%08x\n", GetLastError());
1484 pbTemp
= HeapAlloc(GetProcessHeap(), 0, dwLen
);
1485 CryptGetKeyParam(hKey
, KP_SALT
, pbTemp
, &dwLen
, 0);
1486 HeapFree(GetProcessHeap(), 0, pbTemp
);
1488 dwLen
= sizeof(DWORD
);
1489 CryptGetKeyParam(hKey
, KP_MODE
, (BYTE
*)&dwMode
, &dwLen
, 0);
1491 result
= CryptDestroyHash(hHash
);
1492 ok(result
, "%08x\n", GetLastError());
1495 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, NULL
, &dwDataLen
, 24);
1496 ok(result
, "%08x\n", GetLastError());
1498 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, pbData
, &dwDataLen
, 24);
1499 ok(result
, "%08x\n", GetLastError());
1501 ok(!memcmp(pbData
, rc4
, dwDataLen
), "RC4 encryption failed!\n");
1503 result
= CryptDecrypt(hKey
, 0, TRUE
, 0, pbData
, &dwDataLen
);
1504 ok(result
, "%08x\n", GetLastError());
1506 /* Setting the salt also succeeds... */
1507 result
= CryptSetKeyParam(hKey
, KP_SALT
, pbData
, 0);
1508 ok(result
, "setting salt failed: %08x\n", GetLastError());
1509 /* but the resulting salt length is now zero? */
1511 result
= CryptGetKeyParam(hKey
, KP_SALT
, NULL
, &dwLen
, 0);
1512 ok(result
, "%08x\n", GetLastError());
1514 broken(dwLen
== 11), /* Win9x/WinMe/NT4 */
1515 "unexpected salt length %d\n", dwLen
);
1516 /* What sizes salt can I set? */
1517 salt
.pbData
= pbData
;
1518 for (i
=0; i
<24; i
++)
1521 result
= CryptSetKeyParam(hKey
, KP_SALT_EX
, (BYTE
*)&salt
, 0);
1522 ok(result
, "setting salt failed for size %d: %08x\n", i
, GetLastError());
1523 /* The returned salt length is the same as the set salt length */
1524 result
= CryptGetKeyParam(hKey
, KP_SALT
, NULL
, &dwLen
, 0);
1525 ok(result
, "%08x\n", GetLastError());
1526 ok(dwLen
== i
, "size %d: unexpected salt length %d\n", i
, dwLen
);
1529 SetLastError(0xdeadbeef);
1530 result
= CryptSetKeyParam(hKey
, KP_SALT_EX
, (BYTE
*)&salt
, 0);
1532 broken(result
), /* Win9x, WinMe, NT4, W2K */
1533 "%08x\n", GetLastError());
1535 result
= CryptDestroyKey(hKey
);
1536 ok(result
, "%08x\n", GetLastError());
1540 static void test_hmac(void) {
1544 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1545 HMAC_INFO hmacInfo
= { CALG_MD5
, NULL
, 0, NULL
, 0 };
1548 static const BYTE hmac
[16] = {
1549 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1550 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1553 for (i
=0; i
<sizeof(abData
)/sizeof(BYTE
); i
++) abData
[i
] = (BYTE
)i
;
1555 if (!derive_key(CALG_RC2
, &hKey
, 56)) return;
1557 result
= CryptCreateHash(hProv
, CALG_HMAC
, hKey
, 0, &hHash
);
1558 ok(result
, "%08x\n", GetLastError());
1559 if (!result
) return;
1561 result
= CryptSetHashParam(hHash
, HP_HMAC_INFO
, (BYTE
*)&hmacInfo
, 0);
1562 ok(result
, "%08x\n", GetLastError());
1564 result
= CryptHashData(hHash
, abData
, sizeof(abData
), 0);
1565 ok(result
, "%08x\n", GetLastError());
1567 dwLen
= sizeof(abData
)/sizeof(BYTE
);
1568 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, abData
, &dwLen
, 0);
1569 ok(result
, "%08x\n", GetLastError());
1571 ok(!memcmp(abData
, hmac
, sizeof(hmac
)), "HMAC failed!\n");
1573 result
= CryptDestroyHash(hHash
);
1574 ok(result
, "%08x\n", GetLastError());
1576 result
= CryptDestroyKey(hKey
);
1577 ok(result
, "%08x\n", GetLastError());
1579 /* Provoke errors */
1580 result
= CryptCreateHash(hProv
, CALG_HMAC
, 0, 0, &hHash
);
1581 ok(!result
&& GetLastError() == NTE_BAD_KEY
, "%08x\n", GetLastError());
1584 static void test_mac(void) {
1589 BYTE abData
[256], abEnc
[264];
1590 static const BYTE mac_40
[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1593 for (i
=0; i
<sizeof(abData
)/sizeof(BYTE
); i
++) abData
[i
] = (BYTE
)i
;
1594 for (i
=0; i
<sizeof(abData
)/sizeof(BYTE
); i
++) abEnc
[i
] = (BYTE
)i
;
1596 if (!derive_key(CALG_RC2
, &hKey
, 40)) return;
1599 result
= CryptEncrypt(hKey
, 0, TRUE
, 0, abEnc
, &dwLen
, 264);
1600 ok (result
&& dwLen
== 264, "%08x, dwLen: %d\n", GetLastError(), dwLen
);
1602 result
= CryptCreateHash(hProv
, CALG_MAC
, hKey
, 0, &hHash
);
1603 ok(result
, "%08x\n", GetLastError());
1604 if (!result
) return;
1606 result
= CryptHashData(hHash
, abData
, sizeof(abData
), 0);
1607 ok(result
, "%08x\n", GetLastError());
1609 dwLen
= sizeof(abData
)/sizeof(BYTE
);
1610 result
= CryptGetHashParam(hHash
, HP_HASHVAL
, abData
, &dwLen
, 0);
1611 ok(result
&& dwLen
== 8, "%08x, dwLen: %d\n", GetLastError(), dwLen
);
1613 ok(!memcmp(abData
, mac_40
, sizeof(mac_40
)), "MAC failed!\n");
1615 result
= CryptDestroyHash(hHash
);
1616 ok(result
, "%08x\n", GetLastError());
1618 result
= CryptDestroyKey(hKey
);
1619 ok(result
, "%08x\n", GetLastError());
1621 /* Provoke errors */
1622 if (!derive_key(CALG_RC4
, &hKey
, 56)) return;
1624 SetLastError(0xdeadbeef);
1625 result
= CryptCreateHash(hProv
, CALG_MAC
, hKey
, 0, &hHash
);
1626 ok((!result
&& GetLastError() == NTE_BAD_KEY
) ||
1627 broken(result
), /* Win9x, WinMe, NT4, W2K */
1628 "%08x\n", GetLastError());
1630 result
= CryptDestroyKey(hKey
);
1631 ok(result
, "%08x\n", GetLastError());
1634 static void test_import_private(void)
1637 HCRYPTKEY hKeyExchangeKey
, hSessionKey
;
1639 static BYTE abSessionKey
[148] = {
1640 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1641 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1642 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1643 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1644 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1645 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1646 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1647 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1648 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1649 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1650 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1651 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1652 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1653 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1654 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1655 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1656 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1657 0x04, 0x8c, 0x49, 0x92
1659 static BYTE abEncryptedMessage
[12] = {
1660 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1661 0x1c, 0xfd, 0xde, 0x71
1663 BLOBHEADER
*blobHeader
= (BLOBHEADER
*)abPlainPrivateKey
;
1664 RSAPUBKEY
*rsaPubKey
= (RSAPUBKEY
*)(blobHeader
+1);
1666 dwLen
= (DWORD
)sizeof(abPlainPrivateKey
);
1667 result
= CryptImportKey(hProv
, abPlainPrivateKey
, dwLen
, 0, 0, &hKeyExchangeKey
);
1669 /* rsaenh compiled without OpenSSL */
1670 ok(GetLastError() == NTE_FAIL
, "%08x\n", GetLastError());
1674 dwLen
= (DWORD
)sizeof(abSessionKey
);
1675 result
= CryptImportKey(hProv
, abSessionKey
, dwLen
, hKeyExchangeKey
, 0, &hSessionKey
);
1676 ok(result
, "%08x\n", GetLastError());
1677 if (!result
) return;
1680 dwLen
= sizeof(DWORD
);
1681 result
= CryptGetKeyParam(hSessionKey
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwLen
, 0);
1682 ok(result
, "%08x\n", GetLastError());
1684 (CRYPT_MAC
|CRYPT_WRITE
|CRYPT_READ
|CRYPT_DECRYPT
|CRYPT_ENCRYPT
) ||
1685 broken(dwVal
== 0xffffffff), /* Win9x/NT4 */
1686 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1687 " got %08x\n", dwVal
);
1689 dwLen
= (DWORD
)sizeof(abEncryptedMessage
);
1690 result
= CryptDecrypt(hSessionKey
, 0, TRUE
, 0, abEncryptedMessage
, &dwLen
);
1691 ok(result
&& dwLen
== 12 && !memcmp(abEncryptedMessage
, "Wine rocks!",12),
1692 "%08x, len: %d\n", GetLastError(), dwLen
);
1693 CryptDestroyKey(hSessionKey
);
1695 if (!derive_key(CALG_RC4
, &hSessionKey
, 56)) return;
1697 dwLen
= (DWORD
)sizeof(abSessionKey
);
1698 result
= CryptExportKey(hSessionKey
, hKeyExchangeKey
, SIMPLEBLOB
, 0, abSessionKey
, &dwLen
);
1699 ok(result
, "%08x\n", GetLastError());
1700 CryptDestroyKey(hSessionKey
);
1701 if (!result
) return;
1703 dwLen
= (DWORD
)sizeof(abSessionKey
);
1704 result
= CryptImportKey(hProv
, abSessionKey
, dwLen
, hKeyExchangeKey
, 0, &hSessionKey
);
1705 ok(result
, "%08x\n", GetLastError());
1706 if (!result
) return;
1708 CryptDestroyKey(hSessionKey
);
1709 CryptDestroyKey(hKeyExchangeKey
);
1711 /* Test importing a private key with a buffer that's smaller than the
1712 * actual buffer. The private exponent can be omitted, its length is
1713 * inferred from the passed-in length parameter.
1715 dwLen
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
1716 rsaPubKey
->bitlen
/ 8 + 5 * rsaPubKey
->bitlen
/ 16;
1717 for (; dwLen
< sizeof(abPlainPrivateKey
); dwLen
++)
1719 result
= CryptImportKey(hProv
, abPlainPrivateKey
, dwLen
, 0, 0, &hKeyExchangeKey
);
1720 ok(result
, "CryptImportKey failed at size %d: %d (%08x)\n", dwLen
,
1721 GetLastError(), GetLastError());
1723 CryptDestroyKey(hKeyExchangeKey
);
1727 static void test_verify_signature(void) {
1729 HCRYPTKEY hPubSignKey
;
1730 BYTE abData
[] = "Wine rocks!";
1732 BYTE abPubKey
[148] = {
1733 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1734 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1735 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1736 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1737 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1738 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1739 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1740 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1741 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1742 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1743 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1744 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1745 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1746 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1747 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1748 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1749 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1750 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1751 0xe1, 0x21, 0x50, 0xac
1753 /* md2 with hash oid */
1754 BYTE abSignatureMD2
[128] = {
1755 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1756 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1757 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1758 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1759 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1760 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1761 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1762 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1763 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1764 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1765 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1766 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1767 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1768 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1769 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1770 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1772 /* md2 without hash oid */
1773 BYTE abSignatureMD2NoOID
[128] = {
1774 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1775 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1776 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1777 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1778 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1779 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1780 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1781 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1782 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1783 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1784 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1785 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1786 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1787 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1788 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1789 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1791 /* md4 with hash oid */
1792 BYTE abSignatureMD4
[128] = {
1793 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1794 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1795 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1796 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1797 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1798 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1799 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1800 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1801 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1802 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1803 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1804 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1805 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1806 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1807 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1808 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1810 /* md4 without hash oid */
1811 BYTE abSignatureMD4NoOID
[128] = {
1812 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1813 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1814 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1815 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1816 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1817 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1818 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1819 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1820 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1821 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1822 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1823 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1824 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1825 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1826 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1827 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1829 /* md5 with hash oid */
1830 BYTE abSignatureMD5
[128] = {
1831 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1832 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1833 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1834 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1835 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1836 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1837 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1838 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1839 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1840 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1841 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1842 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1843 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1844 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1845 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1846 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1848 /* md5 without hash oid */
1849 BYTE abSignatureMD5NoOID
[128] = {
1850 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1851 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1852 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1853 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1854 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1855 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1856 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1857 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1858 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1859 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1860 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1861 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1862 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1863 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1864 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1865 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1867 /* sha with hash oid */
1868 BYTE abSignatureSHA
[128] = {
1869 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1870 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1871 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1872 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1873 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1874 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1875 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1876 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1877 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1878 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1879 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1880 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1881 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1882 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1883 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1884 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1886 /* sha without hash oid */
1887 BYTE abSignatureSHANoOID
[128] = {
1888 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1889 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1890 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1891 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1892 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1893 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1894 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1895 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1896 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1897 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1898 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1899 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1900 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1901 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1902 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1903 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1906 result
= CryptImportKey(hProv
, abPubKey
, 148, 0, 0, &hPubSignKey
);
1907 ok(result
, "%08x\n", GetLastError());
1908 if (!result
) return;
1910 result
= CryptCreateHash(hProv
, CALG_MD2
, 0, 0, &hHash
);
1911 ok(result
, "%08x\n", GetLastError());
1912 if (!result
) return;
1914 result
= CryptHashData(hHash
, abData
, (DWORD
)sizeof(abData
), 0);
1915 ok(result
, "%08x\n", GetLastError());
1916 if (!result
) return;
1918 /*check that a NULL pointer signature is correctly handled*/
1919 result
= CryptVerifySignature(hHash
, NULL
, 128, hPubSignKey
, NULL
, 0);
1920 ok(!result
&& ERROR_INVALID_PARAMETER
== GetLastError(),
1921 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1924 /* check that we get a bad signature error when the signature is too short*/
1925 SetLastError(0xdeadbeef);
1926 result
= CryptVerifySignature(hHash
, abSignatureMD2
, 64, hPubSignKey
, NULL
, 0);
1927 ok((!result
&& NTE_BAD_SIGNATURE
== GetLastError()) ||
1928 broken(result
), /* Win9x, WinMe, NT4 */
1929 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1931 result
= CryptVerifySignature(hHash
, abSignatureMD2
, 128, hPubSignKey
, NULL
, 0);
1932 ok(result
, "%08x\n", GetLastError());
1933 if (!result
) return;
1935 /* It seems that CPVerifySignature doesn't care about the OID at all. */
1936 result
= CryptVerifySignature(hHash
, abSignatureMD2NoOID
, 128, hPubSignKey
, NULL
, 0);
1937 ok(result
, "%08x\n", GetLastError());
1938 if (!result
) return;
1940 result
= CryptVerifySignature(hHash
, abSignatureMD2NoOID
, 128, hPubSignKey
, NULL
, CRYPT_NOHASHOID
);
1941 ok(result
, "%08x\n", GetLastError());
1942 if (!result
) return;
1944 CryptDestroyHash(hHash
);
1946 result
= CryptCreateHash(hProv
, CALG_MD4
, 0, 0, &hHash
);
1947 ok(result
, "%08x\n", GetLastError());
1948 if (!result
) return;
1950 result
= CryptHashData(hHash
, abData
, (DWORD
)sizeof(abData
), 0);
1951 ok(result
, "%08x\n", GetLastError());
1952 if (!result
) return;
1954 result
= CryptVerifySignature(hHash
, abSignatureMD4
, 128, hPubSignKey
, NULL
, 0);
1955 ok(result
, "%08x\n", GetLastError());
1956 if (!result
) return;
1958 result
= CryptVerifySignature(hHash
, abSignatureMD4NoOID
, 128, hPubSignKey
, NULL
, 0);
1959 ok(result
, "%08x\n", GetLastError());
1960 if (!result
) return;
1962 result
= CryptVerifySignature(hHash
, abSignatureMD4NoOID
, 128, hPubSignKey
, NULL
, CRYPT_NOHASHOID
);
1963 ok(result
, "%08x\n", GetLastError());
1964 if (!result
) return;
1966 CryptDestroyHash(hHash
);
1968 result
= CryptCreateHash(hProv
, CALG_MD5
, 0, 0, &hHash
);
1969 ok(result
, "%08x\n", GetLastError());
1970 if (!result
) return;
1972 result
= CryptHashData(hHash
, abData
, (DWORD
)sizeof(abData
), 0);
1973 ok(result
, "%08x\n", GetLastError());
1974 if (!result
) return;
1976 result
= CryptVerifySignature(hHash
, abSignatureMD5
, 128, hPubSignKey
, NULL
, 0);
1977 ok(result
, "%08x\n", GetLastError());
1978 if (!result
) return;
1980 result
= CryptVerifySignature(hHash
, abSignatureMD5NoOID
, 128, hPubSignKey
, NULL
, 0);
1981 ok(result
, "%08x\n", GetLastError());
1982 if (!result
) return;
1984 result
= CryptVerifySignature(hHash
, abSignatureMD5NoOID
, 128, hPubSignKey
, NULL
, CRYPT_NOHASHOID
);
1985 ok(result
, "%08x\n", GetLastError());
1986 if (!result
) return;
1988 CryptDestroyHash(hHash
);
1990 result
= CryptCreateHash(hProv
, CALG_SHA
, 0, 0, &hHash
);
1991 ok(result
, "%08x\n", GetLastError());
1992 if (!result
) return;
1994 result
= CryptHashData(hHash
, abData
, (DWORD
)sizeof(abData
), 0);
1995 ok(result
, "%08x\n", GetLastError());
1996 if (!result
) return;
1998 result
= CryptVerifySignature(hHash
, abSignatureSHA
, 128, hPubSignKey
, NULL
, 0);
1999 ok(result
, "%08x\n", GetLastError());
2000 if (!result
) return;
2002 result
= CryptVerifySignature(hHash
, abSignatureSHANoOID
, 128, hPubSignKey
, NULL
, 0);
2003 ok(result
, "%08x\n", GetLastError());
2004 if (!result
) return;
2006 result
= CryptVerifySignature(hHash
, abSignatureSHANoOID
, 128, hPubSignKey
, NULL
, CRYPT_NOHASHOID
);
2007 ok(result
, "%08x\n", GetLastError());
2008 if (!result
) return;
2010 CryptDestroyHash(hHash
);
2011 CryptDestroyKey(hPubSignKey
);
2014 static void test_rsa_encrypt(void)
2017 BYTE abData
[2048] = "Wine rocks!";
2021 /* It is allowed to use the key exchange key for encryption/decryption */
2022 result
= CryptGetUserKey(hProv
, AT_KEYEXCHANGE
, &hRSAKey
);
2023 ok (result
, "%08x\n", GetLastError());
2024 if (!result
) return;
2027 result
= CryptEncrypt(hRSAKey
, 0, TRUE
, 0, NULL
, &dwLen
, (DWORD
)sizeof(abData
));
2028 ok(result
, "CryptEncrypt failed: %08x\n", GetLastError());
2029 ok(dwLen
== 128, "Unexpected length %d\n", dwLen
);
2031 result
= CryptEncrypt(hRSAKey
, 0, TRUE
, 0, abData
, &dwLen
, (DWORD
)sizeof(abData
));
2032 ok (result
, "%08x\n", GetLastError());
2033 if (!result
) return;
2035 result
= CryptDecrypt(hRSAKey
, 0, TRUE
, 0, abData
, &dwLen
);
2036 ok (result
&& dwLen
== 12 && !memcmp(abData
, "Wine rocks!", 12), "%08x\n", GetLastError());
2039 dwLen
= sizeof(DWORD
);
2040 result
= CryptGetKeyParam(hRSAKey
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwLen
, 0);
2041 ok(result
, "%08x\n", GetLastError());
2043 (CRYPT_MAC
|CRYPT_WRITE
|CRYPT_READ
|CRYPT_DECRYPT
|CRYPT_ENCRYPT
) ||
2044 broken(dwVal
== 0xffffffff), /* Win9x/NT4 */
2045 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2046 " got %08x\n", dwVal
);
2048 /* An RSA key doesn't support salt */
2049 result
= CryptGetKeyParam(hRSAKey
, KP_SALT
, NULL
, &dwLen
, 0);
2050 ok(!result
&& (GetLastError() == NTE_BAD_KEY
|| GetLastError() == NTE_NOT_FOUND
/* Win7 */),
2051 "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
2053 /* The key exchange key's public key may be exported.. */
2054 result
= CryptExportKey(hRSAKey
, 0, PUBLICKEYBLOB
, 0, NULL
, &dwLen
);
2055 ok(result
, "%08x\n", GetLastError());
2056 /* but its private key may not be. */
2057 SetLastError(0xdeadbeef);
2058 result
= CryptExportKey(hRSAKey
, 0, PRIVATEKEYBLOB
, 0, NULL
, &dwLen
);
2059 ok((!result
&& GetLastError() == NTE_BAD_KEY_STATE
) ||
2060 broken(result
), /* Win9x/NT4 */
2061 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
2062 /* Setting the permissions of the key exchange key isn't allowed, either. */
2063 dwVal
|= CRYPT_EXPORT
;
2064 SetLastError(0xdeadbeef);
2065 result
= CryptSetKeyParam(hRSAKey
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, 0);
2067 (GetLastError() == NTE_BAD_DATA
|| GetLastError() == NTE_BAD_FLAGS
),
2068 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
2070 CryptDestroyKey(hRSAKey
);
2072 /* It is not allowed to use the signature key for encryption/decryption */
2073 result
= CryptGetUserKey(hProv
, AT_SIGNATURE
, &hRSAKey
);
2074 ok (result
, "%08x\n", GetLastError());
2075 if (!result
) return;
2078 dwLen
= sizeof(DWORD
);
2079 result
= CryptGetKeyParam(hRSAKey
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwLen
, 0);
2080 ok(result
, "%08x\n", GetLastError());
2082 (CRYPT_MAC
|CRYPT_WRITE
|CRYPT_READ
|CRYPT_DECRYPT
|CRYPT_ENCRYPT
) ||
2083 broken(dwVal
== 0xffffffff), /* Win9x/NT4 */
2084 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2085 " got %08x\n", dwVal
);
2087 /* The signature key's public key may also be exported.. */
2088 result
= CryptExportKey(hRSAKey
, 0, PUBLICKEYBLOB
, 0, NULL
, &dwLen
);
2089 ok(result
, "%08x\n", GetLastError());
2090 /* but its private key may not be. */
2091 SetLastError(0xdeadbeef);
2092 result
= CryptExportKey(hRSAKey
, 0, PRIVATEKEYBLOB
, 0, NULL
, &dwLen
);
2093 ok((!result
&& GetLastError() == NTE_BAD_KEY_STATE
) ||
2094 broken(result
), /* Win9x/NT4 */
2095 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
2096 /* Setting the permissions of the signature key isn't allowed, either. */
2097 dwVal
|= CRYPT_EXPORT
;
2098 SetLastError(0xdeadbeef);
2099 result
= CryptSetKeyParam(hRSAKey
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, 0);
2101 (GetLastError() == NTE_BAD_DATA
|| GetLastError() == NTE_BAD_FLAGS
),
2102 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
2105 result
= CryptEncrypt(hRSAKey
, 0, TRUE
, 0, abData
, &dwLen
, (DWORD
)sizeof(abData
));
2106 ok (!result
&& GetLastError() == NTE_BAD_KEY
, "%08x\n", GetLastError());
2108 CryptDestroyKey(hRSAKey
);
2111 static void test_import_export(void)
2113 DWORD dwLen
, dwDataLen
, dwVal
;
2114 HCRYPTKEY hPublicKey
, hPrivKey
;
2117 BYTE emptyKey
[2048], *exported_key
;
2118 static BYTE abPlainPublicKey
[84] = {
2119 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
2120 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
2121 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
2122 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2123 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2124 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2125 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2126 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2127 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2128 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2129 0x11, 0x11, 0x11, 0x11
2131 static BYTE priv_key_with_high_bit
[] = {
2132 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2133 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2134 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2135 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2136 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2137 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2138 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2139 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2140 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2141 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2142 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2143 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2144 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2145 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2146 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2147 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2148 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2149 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2150 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2151 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2152 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2153 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2154 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2155 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2156 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2157 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2158 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2159 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2160 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2161 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2162 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2163 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2164 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2165 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2166 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2167 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2168 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2169 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2170 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2171 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2172 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2173 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2174 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2175 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2176 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2177 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2178 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2179 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2180 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2181 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2182 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2183 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2184 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2185 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2186 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2187 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2188 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2189 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2190 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2191 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2192 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2193 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2194 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2195 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2196 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2197 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2198 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2199 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2200 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2201 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2202 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2203 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2204 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2205 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2206 0xb6, 0x5f, 0x01, 0x5e
2208 static const BYTE expected_exported_priv_key
[] = {
2209 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2210 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2211 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2212 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2213 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2214 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2215 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2216 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2217 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2218 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2219 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2220 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2221 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2222 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2223 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2224 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2225 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2226 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2227 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2228 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2229 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2230 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2231 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2232 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2233 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2234 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2235 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2236 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2237 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2238 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2239 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2240 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2241 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2242 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2243 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2244 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2245 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2246 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2247 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2248 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2249 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2250 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2251 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2252 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2253 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2254 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2255 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2256 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2257 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2258 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2259 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2260 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2261 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2262 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2263 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2264 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2265 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2266 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2267 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2268 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2269 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2270 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2271 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2272 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2273 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2274 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2275 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2276 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2277 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2278 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2279 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2280 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2281 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2282 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2283 0xb6, 0x5f, 0x01, 0x5e
2287 result
= CryptImportKey(hProv
, abPlainPublicKey
, dwLen
, 0, 0, &hPublicKey
);
2288 ok(result
, "failed to import the public key\n");
2290 dwDataLen
=sizeof(algID
);
2291 result
= CryptGetKeyParam(hPublicKey
, KP_ALGID
, (LPBYTE
)&algID
, &dwDataLen
, 0);
2292 ok(result
, "failed to get the KP_ALGID from the imported public key\n");
2293 ok(algID
== CALG_RSA_KEYX
, "Expected CALG_RSA_KEYX, got %x\n", algID
);
2296 dwDataLen
= sizeof(DWORD
);
2297 result
= CryptGetKeyParam(hPublicKey
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwDataLen
, 0);
2298 ok(result
, "%08x\n", GetLastError());
2300 (CRYPT_MAC
|CRYPT_WRITE
|CRYPT_READ
|CRYPT_DECRYPT
|CRYPT_ENCRYPT
) ||
2301 broken(dwVal
== 0xffffffff), /* Win9x/NT4 */
2302 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2303 " got %08x\n", dwVal
);
2304 result
= CryptExportKey(hPublicKey
, 0, PUBLICKEYBLOB
, 0, emptyKey
, &dwLen
);
2305 ok(result
, "failed to export the fresh imported public key\n");
2306 ok(dwLen
== 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen
);
2307 ok(!memcmp(emptyKey
, abPlainPublicKey
, dwLen
), "exported key is different from the imported key\n");
2309 CryptDestroyKey(hPublicKey
);
2311 result
= CryptImportKey(hProv
, priv_key_with_high_bit
,
2312 sizeof(priv_key_with_high_bit
), 0, CRYPT_EXPORTABLE
, &hPrivKey
);
2313 ok(result
, "CryptImportKey failed: %08x\n", GetLastError());
2315 result
= CryptExportKey(hPrivKey
, 0, PRIVATEKEYBLOB
, 0, NULL
, &dwDataLen
);
2316 ok(result
, "CryptExportKey failed: %08x\n", GetLastError());
2317 exported_key
= HeapAlloc(GetProcessHeap(), 0, dwDataLen
);
2318 result
= CryptExportKey(hPrivKey
, 0, PRIVATEKEYBLOB
, 0, exported_key
,
2320 ok(result
, "CryptExportKey failed: %08x\n", GetLastError());
2322 ok(dwDataLen
== sizeof(expected_exported_priv_key
), "unexpected size %d\n",
2324 ok(!memcmp(exported_key
, expected_exported_priv_key
, dwDataLen
),
2325 "unexpected value\n");
2327 HeapFree(GetProcessHeap(), 0, exported_key
);
2329 CryptDestroyKey(hPrivKey
);
2332 static void test_import_hmac(void)
2334 /* Test cases from RFC 2202, section 3 */
2335 static const struct rfc2202_test_case
{
2339 const DWORD data_len
;
2342 { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2343 "\x0b\x0b\x0b\x0b", 20,
2345 "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2346 "\xf1\x46\xbe\x00" },
2348 "what do ya want for nothing?", 28,
2349 "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2350 "\x25\x9a\x7c\x79" },
2351 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2352 "\xaa\xaa\xaa\xaa", 20,
2353 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2354 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2355 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2357 "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2358 "\x63\xf1\x75\xd3" },
2359 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2360 "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2361 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2362 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2363 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2365 "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2366 "\x2d\x72\x35\xda" },
2367 { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2368 "\x0c\x0c\x0c\x0c", 20,
2369 "Test With Truncation", 20,
2370 "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2371 "\x4a\x9a\x5a\x04" },
2372 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2373 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2374 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2375 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2376 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2378 "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2379 "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2380 "\xed\x40\x21\x12" },
2381 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2382 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2383 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2384 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2385 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2387 "Test Using Larger Than Block-Size Key and Larger "
2388 "Than One Block-Size Data", 73,
2389 "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2390 "\xbb\xff\x1a\x91" }
2394 for (i
= 0; i
< sizeof(cases
) / sizeof(cases
[0]); i
++)
2396 const struct rfc2202_test_case
*test_case
= &cases
[i
];
2397 DWORD size
= sizeof(BLOBHEADER
) + sizeof(DWORD
) + test_case
->key_len
;
2398 BYTE
*blob
= HeapAlloc(GetProcessHeap(), 0, size
);
2402 BLOBHEADER
*header
= (BLOBHEADER
*)blob
;
2403 DWORD
*key_len
= (DWORD
*)(header
+ 1);
2404 BYTE
*key_bytes
= (BYTE
*)(key_len
+ 1);
2408 header
->bType
= PLAINTEXTKEYBLOB
;
2409 header
->bVersion
= CUR_BLOB_VERSION
;
2410 header
->reserved
= 0;
2411 header
->aiKeyAlg
= CALG_RC2
;
2412 *key_len
= test_case
->key_len
;
2413 memcpy(key_bytes
, test_case
->key
, *key_len
);
2414 result
= CryptImportKey(hProv
, blob
, size
, 0, CRYPT_IPSEC_HMAC_KEY
, &key
);
2415 ok(result
|| broken(GetLastError() == NTE_BAD_FLAGS
/* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i
, GetLastError());
2419 HMAC_INFO hmac_info
= { CALG_SHA1
, 0 };
2423 result
= CryptCreateHash(hProv
, CALG_HMAC
, key
, 0, &hash
);
2424 ok(result
, "CryptCreateHash failed on test case %d: %08x\n", i
, GetLastError());
2425 result
= CryptSetHashParam(hash
, HP_HMAC_INFO
, (BYTE
*)&hmac_info
, 0);
2426 ok(result
, "CryptSetHashParam failed on test case %d: %08x\n", i
, GetLastError());
2427 result
= CryptHashData(hash
, (const BYTE
*)test_case
->data
, test_case
->data_len
, 0);
2428 ok(result
, "CryptHashData failed on test case %d: %08x\n", i
, GetLastError());
2429 digest_size
= sizeof(digest
);
2430 result
= CryptGetHashParam(hash
, HP_HASHVAL
, digest
, &digest_size
, 0);
2431 ok(result
, "CryptGetHashParam failed on test case %d: %08x\n", i
, GetLastError());
2432 ok(!memcmp(digest
, test_case
->digest
, sizeof(digest
)), "Unexpected value on test case %d\n", i
);
2433 CryptDestroyHash(hash
);
2434 CryptDestroyKey(key
);
2436 HeapFree(GetProcessHeap(), 0, blob
);
2441 static void test_schannel_provider(void)
2444 HCRYPTKEY hRSAKey
, hMasterSecret
, hServerWriteKey
, hServerWriteMACKey
;
2445 HCRYPTHASH hMasterHash
, hTLS1PRF
, hHMAC
;
2448 SCHANNEL_ALG saSChannelAlg
;
2449 CRYPT_DATA_BLOB data_blob
;
2450 HMAC_INFO hmacInfo
= { CALG_MD5
, NULL
, 0, NULL
, 0 };
2451 BYTE abTLS1Master
[140] = {
2452 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2453 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2454 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2455 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2456 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2457 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2458 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2459 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2460 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2461 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2462 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2463 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2464 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2465 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2466 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2467 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2468 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2469 0xd3, 0x1e, 0x82, 0xb3
2471 BYTE abServerSecret
[33] = "Super Secret Server Secret 12345";
2472 BYTE abClientSecret
[33] = "Super Secret Client Secret 12345";
2473 BYTE abHashedHandshakes
[37] = "123456789012345678901234567890123456";
2474 BYTE abClientFinished
[16] = "client finished";
2475 BYTE abData
[16] = "Wine rocks!";
2477 static const BYTE abEncryptedData
[16] = {
2478 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2479 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2481 static const BYTE abPRF
[16] = {
2482 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2483 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2485 static const BYTE abMD5
[16] = {
2486 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2487 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2490 result
= CryptAcquireContext(&hProv
, NULL
, NULL
, PROV_RSA_SCHANNEL
, CRYPT_VERIFYCONTEXT
|CRYPT_NEWKEYSET
);
2493 win_skip("no PROV_RSA_SCHANNEL support\n");
2496 ok (result
, "%08x\n", GetLastError());
2498 CryptReleaseContext(hProv
, 0);
2500 result
= CryptAcquireContext(&hProv
, NULL
, NULL
, PROV_RSA_SCHANNEL
, CRYPT_VERIFYCONTEXT
);
2501 ok (result
, "%08x\n", GetLastError());
2502 if (!result
) return;
2504 /* To get deterministic results, we import the TLS1 master secret (which
2505 * is typically generated from a random generator). Therefore, we need
2507 dwLen
= (DWORD
)sizeof(abPlainPrivateKey
);
2508 result
= CryptImportKey(hProv
, abPlainPrivateKey
, dwLen
, 0, 0, &hRSAKey
);
2509 ok (result
, "%08x\n", GetLastError());
2510 if (!result
) return;
2512 dwLen
= (DWORD
)sizeof(abTLS1Master
);
2513 result
= CryptImportKey(hProv
, abTLS1Master
, dwLen
, hRSAKey
, 0, &hMasterSecret
);
2514 ok (result
, "%08x\n", GetLastError());
2515 if (!result
) return;
2517 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2518 * (Keys can only be derived from hashes, not from other keys.)
2519 * The hash can't be created yet because the key doesn't have the client
2520 * random or server random set.
2522 result
= CryptCreateHash(hProv
, CALG_SCHANNEL_MASTER_HASH
, hMasterSecret
, 0, &hMasterHash
);
2523 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2524 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2526 /* Setting the TLS1 client and server random parameters, as well as the
2527 * MAC and encryption algorithm parameters. */
2528 data_blob
.cbData
= 33;
2529 data_blob
.pbData
= abClientSecret
;
2530 result
= CryptSetKeyParam(hMasterSecret
, KP_CLIENT_RANDOM
, (BYTE
*)&data_blob
, 0);
2531 ok (result
, "%08x\n", GetLastError());
2532 if (!result
) return;
2534 data_blob
.cbData
= 33;
2535 data_blob
.pbData
= abServerSecret
;
2536 result
= CryptSetKeyParam(hMasterSecret
, KP_SERVER_RANDOM
, (BYTE
*)&data_blob
, 0);
2537 ok (result
, "%08x\n", GetLastError());
2538 if (!result
) return;
2540 result
= CryptCreateHash(hProv
, CALG_SCHANNEL_MASTER_HASH
, hMasterSecret
, 0, &hMasterHash
);
2541 ok (result
, "%08x\n", GetLastError());
2542 if (!result
) return;
2544 /* Deriving the server write encryption key from the master hash can't
2545 * succeed before the encryption key algorithm is set.
2547 result
= CryptDeriveKey(hProv
, CALG_SCHANNEL_ENC_KEY
, hMasterHash
, CRYPT_SERVER
, &hServerWriteKey
);
2548 ok (!result
&& GetLastError() == NTE_BAD_FLAGS
,
2549 "expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2551 CryptDestroyHash(hMasterHash
);
2553 saSChannelAlg
.dwUse
= SCHANNEL_ENC_KEY
;
2554 saSChannelAlg
.Algid
= CALG_DES
;
2555 saSChannelAlg
.cBits
= 64;
2556 saSChannelAlg
.dwFlags
= 0;
2557 saSChannelAlg
.dwReserved
= 0;
2558 result
= CryptSetKeyParam(hMasterSecret
, KP_SCHANNEL_ALG
, (PBYTE
)&saSChannelAlg
, 0);
2559 ok (result
, "%08x\n", GetLastError());
2560 if (!result
) return;
2562 saSChannelAlg
.dwUse
= SCHANNEL_MAC_KEY
;
2563 saSChannelAlg
.Algid
= CALG_MD5
;
2564 saSChannelAlg
.cBits
= 128;
2565 saSChannelAlg
.dwFlags
= 0;
2566 saSChannelAlg
.dwReserved
= 0;
2567 result
= CryptSetKeyParam(hMasterSecret
, KP_SCHANNEL_ALG
, (PBYTE
)&saSChannelAlg
, 0);
2568 ok (result
, "%08x\n", GetLastError());
2569 if (!result
) return;
2571 result
= CryptCreateHash(hProv
, CALG_SCHANNEL_MASTER_HASH
, hMasterSecret
, 0, &hMasterHash
);
2572 ok (result
, "%08x\n", GetLastError());
2573 if (!result
) return;
2575 /* Deriving the server write encryption key from the master hash */
2576 result
= CryptDeriveKey(hProv
, CALG_SCHANNEL_ENC_KEY
, hMasterHash
, CRYPT_SERVER
, &hServerWriteKey
);
2577 ok (result
, "%08x\n", GetLastError());
2578 if (!result
) return;
2580 /* Encrypting some data with the server write encryption key and checking the result. */
2582 result
= CryptEncrypt(hServerWriteKey
, 0, TRUE
, 0, abData
, &dwLen
, 16);
2583 ok (result
&& (dwLen
== 16) && !memcmp(abData
, abEncryptedData
, 16), "%08x\n", GetLastError());
2585 /* Second test case: Test the TLS1 pseudo random number function. */
2586 result
= CryptCreateHash(hProv
, CALG_TLS1PRF
, hMasterSecret
, 0, &hTLS1PRF
);
2587 ok (result
, "%08x\n", GetLastError());
2588 if (!result
) return;
2590 /* Set the label and seed parameters for the random number function */
2591 data_blob
.cbData
= 36;
2592 data_blob
.pbData
= abHashedHandshakes
;
2593 result
= CryptSetHashParam(hTLS1PRF
, HP_TLS1PRF_SEED
, (BYTE
*)&data_blob
, 0);
2594 ok (result
, "%08x\n", GetLastError());
2595 if (!result
) return;
2597 data_blob
.cbData
= 15;
2598 data_blob
.pbData
= abClientFinished
;
2599 result
= CryptSetHashParam(hTLS1PRF
, HP_TLS1PRF_LABEL
, (BYTE
*)&data_blob
, 0);
2600 ok (result
, "%08x\n", GetLastError());
2601 if (!result
) return;
2603 /* Generate some pseudo random bytes and check if they are correct. */
2604 dwLen
= (DWORD
)sizeof(abData
);
2605 result
= CryptGetHashParam(hTLS1PRF
, HP_HASHVAL
, abData
, &dwLen
, 0);
2606 ok (result
&& (dwLen
==(DWORD
)sizeof(abData
)) && !memcmp(abData
, abPRF
, sizeof(abData
)),
2607 "%08x\n", GetLastError());
2609 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2610 * Hash some data with the HMAC. Compare results. */
2611 result
= CryptDeriveKey(hProv
, CALG_SCHANNEL_MAC_KEY
, hMasterHash
, CRYPT_SERVER
, &hServerWriteMACKey
);
2612 ok (result
, "%08x\n", GetLastError());
2613 if (!result
) return;
2615 result
= CryptCreateHash(hProv
, CALG_HMAC
, hServerWriteMACKey
, 0, &hHMAC
);
2616 ok (result
, "%08x\n", GetLastError());
2617 if (!result
) return;
2619 result
= CryptSetHashParam(hHMAC
, HP_HMAC_INFO
, (PBYTE
)&hmacInfo
, 0);
2620 ok (result
, "%08x\n", GetLastError());
2621 if (!result
) return;
2623 result
= CryptHashData(hHMAC
, abData
, (DWORD
)sizeof(abData
), 0);
2624 ok (result
, "%08x\n", GetLastError());
2625 if (!result
) return;
2627 dwLen
= (DWORD
)sizeof(abMD5Hash
);
2628 result
= CryptGetHashParam(hHMAC
, HP_HASHVAL
, abMD5Hash
, &dwLen
, 0);
2629 ok (result
&& (dwLen
== 16) && !memcmp(abMD5Hash
, abMD5
, 16), "%08x\n", GetLastError());
2631 CryptDestroyHash(hHMAC
);
2632 CryptDestroyHash(hTLS1PRF
);
2633 CryptDestroyHash(hMasterHash
);
2634 CryptDestroyKey(hServerWriteMACKey
);
2635 CryptDestroyKey(hServerWriteKey
);
2636 CryptDestroyKey(hRSAKey
);
2637 CryptDestroyKey(hMasterSecret
);
2638 CryptReleaseContext(hProv
, 0);
2639 CryptAcquireContext(&hProv
, NULL
, NULL
, PROV_RSA_SCHANNEL
, CRYPT_DELETEKEYSET
);
2642 /* Test that a key can be used to encrypt data and exported, and that, when
2643 * the exported key is imported again, can be used to decrypt the original
2646 static void test_rsa_round_trip(void)
2648 static const char test_string
[] = "Well this is a fine how-do-you-do.";
2650 HCRYPTKEY signKey
, keyExchangeKey
;
2652 BYTE data
[256], *exportedKey
;
2653 DWORD dataLen
, keyLen
;
2655 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2656 CRYPT_DELETEKEYSET
);
2658 /* Generate a new key... */
2659 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2661 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
2662 result
= CryptGenKey(prov
, CALG_RSA_KEYX
, CRYPT_EXPORTABLE
, &signKey
);
2663 ok(result
, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2664 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &keyExchangeKey
);
2665 ok(result
, "CryptGetUserKey failed: %08x\n", GetLastError());
2666 /* encrypt some data with it... */
2667 memcpy(data
, test_string
, strlen(test_string
) + 1);
2668 dataLen
= strlen(test_string
) + 1;
2669 result
= CryptEncrypt(keyExchangeKey
, 0, TRUE
, 0, data
, &dataLen
,
2671 ok(result
|| broken(GetLastError() == NTE_BAD_KEY
/* Win9x/2000 */) ||
2672 broken(GetLastError() == NTE_PERM
/* NT4 */),
2673 "CryptEncrypt failed: %08x\n", GetLastError());
2674 /* export the key... */
2675 result
= CryptExportKey(keyExchangeKey
, 0, PRIVATEKEYBLOB
, 0, NULL
,
2677 ok(result
, "CryptExportKey failed: %08x\n", GetLastError());
2678 exportedKey
= HeapAlloc(GetProcessHeap(), 0, keyLen
);
2679 result
= CryptExportKey(keyExchangeKey
, 0, PRIVATEKEYBLOB
, 0, exportedKey
,
2681 ok(result
, "CryptExportKey failed: %08x\n", GetLastError());
2682 /* destroy the key... */
2683 CryptDestroyKey(keyExchangeKey
);
2684 CryptDestroyKey(signKey
);
2685 /* import the key again... */
2686 result
= CryptImportKey(prov
, exportedKey
, keyLen
, 0, 0, &keyExchangeKey
);
2687 ok(result
, "CryptImportKey failed: %08x\n", GetLastError());
2688 HeapFree(GetProcessHeap(), 0, exportedKey
);
2689 /* and decrypt the data encrypted with the original key with the imported
2692 result
= CryptDecrypt(keyExchangeKey
, 0, TRUE
, 0, data
, &dataLen
);
2693 ok(result
|| broken(GetLastError() == NTE_BAD_KEY
/* Win9x/2000 */) ||
2694 broken(GetLastError() == NTE_PERM
/* NT4 */),
2695 "CryptDecrypt failed: %08x\n", GetLastError());
2698 ok(dataLen
== sizeof(test_string
), "unexpected size %d\n", dataLen
);
2699 ok(!memcmp(data
, test_string
, sizeof(test_string
)), "unexpected value\n");
2701 CryptDestroyKey(keyExchangeKey
);
2702 CryptReleaseContext(prov
, 0);
2704 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2705 CRYPT_DELETEKEYSET
);
2708 static void test_enum_container(void)
2710 BYTE abContainerName
[MAX_PATH
+ 2]; /* Larger than maximum name len */
2712 BOOL result
, fFound
= FALSE
;
2714 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2715 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2716 SetLastError(0xdeadbeef);
2717 result
= CryptGetProvParam(hProv
, PP_ENUMCONTAINERS
, NULL
, &dwBufferLen
, CRYPT_FIRST
);
2718 ok (result
, "%08x\n", GetLastError());
2719 ok (dwBufferLen
== MAX_PATH
+ 1 ||
2720 broken(dwBufferLen
!= MAX_PATH
+ 1), /* Win9x, WinMe, NT4 */
2721 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen
);
2723 /* If the result fits into abContainerName dwBufferLen is left untouched */
2724 dwBufferLen
= (DWORD
)sizeof(abContainerName
);
2725 result
= CryptGetProvParam(hProv
, PP_ENUMCONTAINERS
, abContainerName
, &dwBufferLen
, CRYPT_FIRST
);
2726 ok (result
&& dwBufferLen
== (DWORD
)sizeof(abContainerName
), "%08x\n", GetLastError());
2728 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2730 if (!strcmp((const char*)abContainerName
, "winetest")) fFound
= TRUE
;
2731 dwBufferLen
= (DWORD
)sizeof(abContainerName
);
2732 } while (CryptGetProvParam(hProv
, PP_ENUMCONTAINERS
, abContainerName
, &dwBufferLen
, 0));
2734 ok (fFound
&& GetLastError() == ERROR_NO_MORE_ITEMS
, "%d, %08x\n", fFound
, GetLastError());
2737 static BYTE signBlob
[] = {
2738 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2739 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2740 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2741 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2742 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2743 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2744 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2745 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2746 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2747 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2748 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2749 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2750 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2751 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2752 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2753 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2754 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2755 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2756 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2757 0xb6,0x85,0x86,0x07 };
2759 static void test_null_provider(void)
2764 DWORD keySpec
, dataLen
,dwParam
;
2765 char szName
[MAX_PATH
];
2767 result
= CryptAcquireContext(NULL
, szContainer
, NULL
, 0, 0);
2768 ok(!result
&& GetLastError() == NTE_BAD_PROV_TYPE
,
2769 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2770 result
= CryptAcquireContext(NULL
, szContainer
, NULL
, PROV_RSA_FULL
, 0);
2771 ok(!result
&& (GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == NTE_BAD_KEYSET
),
2772 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2773 result
= CryptAcquireContext(NULL
, szContainer
, NULL
, PROV_RSA_FULL
,
2774 CRYPT_DELETEKEYSET
);
2775 ok(!result
&& ( GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == NTE_BAD_KEYSET
),
2776 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2777 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2778 CRYPT_DELETEKEYSET
);
2779 ok(!result
&& GetLastError() == NTE_BAD_KEYSET
,
2780 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2781 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
, 0);
2782 ok(!result
&& GetLastError() == NTE_BAD_KEYSET
,
2783 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2785 /* Delete the default container. */
2786 CryptAcquireContext(&prov
, NULL
, NULL
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
2787 /* Once you've deleted the default container you can't open it as if it
2790 result
= CryptAcquireContext(&prov
, NULL
, NULL
, PROV_RSA_FULL
, 0);
2791 ok(!result
&& GetLastError() == NTE_BAD_KEYSET
,
2792 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2793 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2794 result
= CryptAcquireContext(&prov
, NULL
, NULL
, PROV_RSA_FULL
,
2795 CRYPT_VERIFYCONTEXT
);
2796 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
2797 if (!result
) return;
2798 dataLen
= sizeof(keySpec
);
2799 result
= CryptGetProvParam(prov
, PP_KEYSPEC
, (LPBYTE
)&keySpec
, &dataLen
, 0);
2801 ok(keySpec
== (AT_KEYEXCHANGE
| AT_SIGNATURE
),
2802 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec
);
2803 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2804 * supported, you can't get the keys from this container.
2806 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2807 ok(!result
&& GetLastError() == NTE_NO_KEY
,
2808 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2809 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
2810 ok(!result
&& GetLastError() == NTE_NO_KEY
,
2811 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2812 result
= CryptReleaseContext(prov
, 0);
2813 ok(result
, "CryptReleaseContext failed: %08x\n", GetLastError());
2814 /* You can create a new default container. */
2815 result
= CryptAcquireContext(&prov
, NULL
, NULL
, PROV_RSA_FULL
,
2817 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
2818 /* But you still can't get the keys (until one's been generated.) */
2819 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2820 ok(!result
&& GetLastError() == NTE_NO_KEY
,
2821 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2822 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
2823 ok(!result
&& GetLastError() == NTE_NO_KEY
,
2824 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2825 CryptReleaseContext(prov
, 0);
2826 CryptAcquireContext(&prov
, NULL
, NULL
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
2828 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2829 CRYPT_DELETEKEYSET
);
2830 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
, 0);
2831 ok(!result
&& GetLastError() == NTE_BAD_KEYSET
,
2832 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2833 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2834 CRYPT_VERIFYCONTEXT
);
2835 ok(!result
&& GetLastError() == NTE_BAD_FLAGS
,
2836 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2837 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2839 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
2840 if (!result
) return;
2841 /* Test provider parameters getter */
2842 dataLen
= sizeof(dwParam
);
2843 result
= CryptGetProvParam(prov
, PP_PROVTYPE
, (LPBYTE
)&dwParam
, &dataLen
, 0);
2844 ok(result
&& dataLen
== sizeof(dwParam
) && dwParam
== PROV_RSA_FULL
,
2845 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam
);
2846 dataLen
= sizeof(dwParam
);
2847 result
= CryptGetProvParam(prov
, PP_KEYSET_TYPE
, (LPBYTE
)&dwParam
, &dataLen
, 0);
2848 ok(result
&& dataLen
== sizeof(dwParam
) && dwParam
== 0,
2849 "Expected 0, got 0x%08X\n",dwParam
);
2850 dataLen
= sizeof(dwParam
);
2851 result
= CryptGetProvParam(prov
, PP_KEYSTORAGE
, (LPBYTE
)&dwParam
, &dataLen
, 0);
2852 ok(result
&& dataLen
== sizeof(dwParam
) && (dwParam
& CRYPT_SEC_DESCR
),
2853 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam
);
2854 dataLen
= sizeof(keySpec
);
2855 SetLastError(0xdeadbeef);
2856 result
= CryptGetProvParam(prov
, PP_KEYSPEC
, (LPBYTE
)&keySpec
, &dataLen
, 0);
2857 if (!result
&& GetLastError() == NTE_BAD_TYPE
)
2858 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2860 ok(result
&& keySpec
== (AT_KEYEXCHANGE
| AT_SIGNATURE
),
2861 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec
);
2862 /* PP_CONTAINER parameter */
2863 dataLen
= sizeof(szName
);
2864 result
= CryptGetProvParam(prov
, PP_CONTAINER
, (LPBYTE
)szName
, &dataLen
, 0);
2865 ok(result
&& dataLen
== strlen(szContainer
)+1 && strcmp(szContainer
,szName
) == 0,
2866 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2867 (result
)? "TRUE":"FALSE",GetLastError(),dataLen
);
2868 /* PP_UNIQUE_CONTAINER parameter */
2869 dataLen
= sizeof(szName
);
2870 SetLastError(0xdeadbeef);
2871 result
= CryptGetProvParam(prov
, PP_UNIQUE_CONTAINER
, (LPBYTE
)szName
, &dataLen
, 0);
2872 if (!result
&& GetLastError() == NTE_BAD_TYPE
)
2874 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2878 char container
[MAX_PATH
];
2880 ok(result
, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2881 uniquecontainer(container
);
2884 ok(dataLen
== strlen(container
)+1 ||
2885 broken(dataLen
== strlen(szContainer
)+1) /* WinME */,
2886 "Expected a param length of 70, got %d\n", dataLen
);
2887 ok(!strcmp(container
, szName
) ||
2888 broken(!strcmp(szName
, szContainer
)) /* WinME */,
2889 "Wrong container name : %s\n", szName
);
2892 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2893 ok(!result
&& GetLastError() == NTE_NO_KEY
,
2894 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2895 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
2896 ok(!result
&& GetLastError() == NTE_NO_KEY
,
2897 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2899 /* Importing a key exchange blob.. */
2900 result
= CryptImportKey(prov
, abPlainPrivateKey
, sizeof(abPlainPrivateKey
),
2902 ok(result
, "CryptImportKey failed: %08x\n", GetLastError());
2903 CryptDestroyKey(key
);
2904 /* allows access to the key exchange key.. */
2905 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2906 ok(result
, "CryptGetUserKey failed: %08x\n", GetLastError());
2907 CryptDestroyKey(key
);
2908 /* but not to the private key. */
2909 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
2910 ok(!result
&& GetLastError() == NTE_NO_KEY
,
2911 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2912 CryptReleaseContext(prov
, 0);
2913 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2914 CRYPT_DELETEKEYSET
);
2916 /* Whereas importing a sign blob.. */
2917 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2919 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
2920 if (!result
) return;
2921 result
= CryptImportKey(prov
, signBlob
, sizeof(signBlob
), 0, 0, &key
);
2922 ok(result
, "CryptImportKey failed: %08x\n", GetLastError());
2923 CryptDestroyKey(key
);
2924 /* doesn't allow access to the key exchange key.. */
2925 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2926 ok(!result
&& GetLastError() == NTE_NO_KEY
,
2927 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2928 /* but does to the private key. */
2929 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
2930 ok(result
, "CryptGetUserKey failed: %08x\n", GetLastError());
2931 CryptDestroyKey(key
);
2932 CryptReleaseContext(prov
, 0);
2934 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2935 CRYPT_DELETEKEYSET
);
2937 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2938 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2940 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
2941 result
= CryptGenKey(prov
, CALG_RSA_SIGN
, 0, &key
);
2942 ok(result
, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2943 CryptDestroyKey(key
);
2944 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2945 ok(!result
, "expected CryptGetUserKey to fail\n");
2946 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
2947 ok(result
, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2948 CryptDestroyKey(key
);
2949 CryptReleaseContext(prov
, 0);
2951 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2952 CRYPT_DELETEKEYSET
);
2954 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2955 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2957 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
2958 result
= CryptGenKey(prov
, CALG_RSA_KEYX
, 0, &key
);
2959 ok(result
, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2960 CryptDestroyKey(key
);
2961 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2962 ok(result
, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2963 CryptDestroyKey(key
);
2964 result
= CryptGetUserKey(prov
, AT_SIGNATURE
, &key
);
2965 ok(!result
, "expected CryptGetUserKey to fail\n");
2966 CryptReleaseContext(prov
, 0);
2968 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2969 CRYPT_DELETEKEYSET
);
2971 /* test for the bug in accessing the user key in a container
2973 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2975 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
2976 result
= CryptGenKey(prov
, AT_KEYEXCHANGE
, 0, &key
);
2977 ok(result
, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2978 CryptDestroyKey(key
);
2979 CryptReleaseContext(prov
,0);
2980 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,0);
2981 ok(result
, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2982 result
= CryptGetUserKey(prov
, AT_KEYEXCHANGE
, &key
);
2983 ok (result
, "CryptGetUserKey failed with error %08x\n", GetLastError());
2984 CryptDestroyKey(key
);
2985 CryptReleaseContext(prov
, 0);
2987 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2988 CRYPT_DELETEKEYSET
);
2990 /* test the machine key set */
2991 CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2992 CRYPT_DELETEKEYSET
|CRYPT_MACHINE_KEYSET
);
2993 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2994 CRYPT_NEWKEYSET
|CRYPT_MACHINE_KEYSET
);
2995 ok(result
, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2996 CryptReleaseContext(prov
, 0);
2997 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
2998 CRYPT_MACHINE_KEYSET
);
2999 ok(result
, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
3000 CryptReleaseContext(prov
,0);
3001 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
3002 CRYPT_DELETEKEYSET
|CRYPT_MACHINE_KEYSET
);
3003 ok(result
, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
3005 result
= CryptAcquireContext(&prov
, szContainer
, NULL
, PROV_RSA_FULL
,
3006 CRYPT_MACHINE_KEYSET
);
3007 ok(!result
&& GetLastError() == NTE_BAD_KEYSET
,
3008 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3012 static void test_key_permissions(void)
3014 HCRYPTKEY hKey1
, hKey2
;
3018 /* Create keys that are exportable */
3019 if (!init_base_environment(CRYPT_EXPORTABLE
))
3022 result
= CryptGetUserKey(hProv
, AT_KEYEXCHANGE
, &hKey1
);
3023 ok (result
, "%08x\n", GetLastError());
3024 if (!result
) return;
3027 dwLen
= sizeof(DWORD
);
3028 result
= CryptGetKeyParam(hKey1
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwLen
, 0);
3029 ok(result
, "%08x\n", GetLastError());
3031 (CRYPT_MAC
|CRYPT_WRITE
|CRYPT_READ
|CRYPT_EXPORT
|CRYPT_DECRYPT
|CRYPT_ENCRYPT
) ||
3032 broken(dwVal
== 0xffffffff), /* Win9x/NT4 */
3033 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3034 " got %08x\n", dwVal
);
3036 /* The key exchange key's public key may be exported.. */
3037 result
= CryptExportKey(hKey1
, 0, PUBLICKEYBLOB
, 0, NULL
, &dwLen
);
3038 ok(result
, "%08x\n", GetLastError());
3039 /* and its private key may be too. */
3040 result
= CryptExportKey(hKey1
, 0, PRIVATEKEYBLOB
, 0, NULL
, &dwLen
);
3041 ok(result
, "%08x\n", GetLastError());
3042 /* Turning off the key's export permissions is "allowed".. */
3043 dwVal
&= ~CRYPT_EXPORT
;
3044 result
= CryptSetKeyParam(hKey1
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, 0);
3046 broken(!result
&& GetLastError() == NTE_BAD_DATA
) || /* W2K */
3047 broken(!result
&& GetLastError() == NTE_BAD_FLAGS
), /* Win9x/WinME/NT4 */
3048 "%08x\n", GetLastError());
3049 /* but it has no effect. */
3051 dwLen
= sizeof(DWORD
);
3052 result
= CryptGetKeyParam(hKey1
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwLen
, 0);
3053 ok(result
, "%08x\n", GetLastError());
3055 (CRYPT_MAC
|CRYPT_WRITE
|CRYPT_READ
|CRYPT_EXPORT
|CRYPT_DECRYPT
|CRYPT_ENCRYPT
) ||
3056 broken(dwVal
== 0xffffffff), /* Win9x/NT4 */
3057 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3058 " got %08x\n", dwVal
);
3059 /* Thus, changing the export flag of the key doesn't affect whether the key
3062 result
= CryptExportKey(hKey1
, 0, PRIVATEKEYBLOB
, 0, NULL
, &dwLen
);
3063 ok(result
, "%08x\n", GetLastError());
3065 result
= CryptGetUserKey(hProv
, AT_KEYEXCHANGE
, &hKey2
);
3066 ok (result
, "%08x\n", GetLastError());
3068 /* A subsequent get of the same key, into a different handle, also doesn't
3069 * show that the permissions have been changed.
3072 dwLen
= sizeof(DWORD
);
3073 result
= CryptGetKeyParam(hKey2
, KP_PERMISSIONS
, (BYTE
*)&dwVal
, &dwLen
, 0);
3074 ok(result
, "%08x\n", GetLastError());
3076 (CRYPT_MAC
|CRYPT_WRITE
|CRYPT_READ
|CRYPT_EXPORT
|CRYPT_DECRYPT
|CRYPT_ENCRYPT
) ||
3077 broken(dwVal
== 0xffffffff), /* Win9x/NT4 */
3078 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3079 " got %08x\n", dwVal
);
3081 CryptDestroyKey(hKey2
);
3082 CryptDestroyKey(hKey1
);
3084 clean_up_base_environment();
3087 static void test_key_initialization(void)
3090 HCRYPTPROV prov1
, prov2
;
3091 HCRYPTKEY hKeyExchangeKey
, hSessionKey
, hKey
;
3093 static BYTE abSessionKey
[148] = {
3094 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
3095 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
3096 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
3097 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
3098 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
3099 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
3100 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
3101 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
3102 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
3103 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
3104 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
3105 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
3106 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
3107 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
3108 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
3109 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
3110 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
3111 0x04, 0x8c, 0x49, 0x92
3114 /* Like init_base_environment, but doesn't generate new keys, as they'll
3115 * be imported instead.
3117 if (!CryptAcquireContext(&prov1
, szContainer
, szProvider
, PROV_RSA_FULL
, 0))
3119 result
= CryptAcquireContext(&prov1
, szContainer
, szProvider
, PROV_RSA_FULL
,
3121 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
3123 dwLen
= (DWORD
)sizeof(abPlainPrivateKey
);
3124 result
= CryptImportKey(prov1
, abPlainPrivateKey
, dwLen
, 0, 0, &hKeyExchangeKey
);
3125 ok(result
, "CryptImportKey failed: %08x\n", GetLastError());
3127 dwLen
= (DWORD
)sizeof(abSessionKey
);
3128 result
= CryptImportKey(prov1
, abSessionKey
, dwLen
, hKeyExchangeKey
, 0, &hSessionKey
);
3129 ok(result
, "CryptImportKey failed: %08x\n", GetLastError());
3131 /* Once the key has been imported, subsequently acquiring a context with
3132 * the same name will allow retrieving the key.
3134 result
= CryptAcquireContext(&prov2
, szContainer
, szProvider
, PROV_RSA_FULL
, 0);
3135 ok(result
, "CryptAcquireContext failed: %08x\n", GetLastError());
3136 result
= CryptGetUserKey(prov2
, AT_KEYEXCHANGE
, &hKey
);
3137 ok(result
, "CryptGetUserKey failed: %08x\n", GetLastError());
3138 if (result
) CryptDestroyKey(hKey
);
3139 CryptReleaseContext(prov2
, 0);
3141 CryptDestroyKey(hSessionKey
);
3142 CryptDestroyKey(hKeyExchangeKey
);
3143 CryptReleaseContext(prov1
, 0);
3144 CryptAcquireContext(&prov1
, szContainer
, NULL
, PROV_RSA_FULL
,
3145 CRYPT_DELETEKEYSET
);
3150 if (!init_base_environment(0))
3162 test_block_cipher_modes();
3163 test_import_private();
3164 test_verify_signature();
3166 test_import_export();
3168 test_enum_container();
3169 clean_up_base_environment();
3170 test_key_permissions();
3171 test_key_initialization();
3172 test_schannel_provider();
3173 test_null_provider();
3174 test_rsa_round_trip();
3175 if (!init_aes_environment())
3181 clean_up_aes_environment();