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 = CryptDestroyHash(hHash);
666 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
667 result = CryptReleaseContext(prov, 0);
668 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
671 static void test_block_cipher_modes(void)
673 static const BYTE plain[23] = {
674 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
675 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
676 static const BYTE ecb[24] = {
677 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
678 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
679 static const BYTE cbc[24] = {
680 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
681 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
682 static const BYTE cfb[24] = {
683 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
684 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
690 result = derive_key(CALG_RC2, &hKey, 40);
693 memcpy(abData, plain, sizeof(plain));
695 dwMode = CRYPT_MODE_ECB;
696 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
697 ok(result, "%08x\n", GetLastError());
699 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
700 ok(result, "%08x\n", GetLastError());
701 ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
704 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
705 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
706 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
708 SetLastError(ERROR_SUCCESS);
710 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
711 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
712 "%08x, dwLen: %d\n", GetLastError(), dwLen);
714 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
715 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
716 "%08x, dwLen: %d\n", GetLastError(), dwLen);
718 dwMode = CRYPT_MODE_CBC;
719 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
720 ok(result, "%08x\n", GetLastError());
723 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
724 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
725 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
728 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
729 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
730 "%08x, dwLen: %d\n", GetLastError(), dwLen);
732 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
733 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
734 "%08x, dwLen: %d\n", GetLastError(), dwLen);
736 dwMode = CRYPT_MODE_CFB;
737 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
738 ok(result, "%08x\n", GetLastError());
741 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
742 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
745 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
746 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
747 "%08x, dwLen: %d\n", GetLastError(), dwLen);
750 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
751 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
754 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
755 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
756 "%08x, dwLen: %d\n", GetLastError(), dwLen);
758 dwMode = CRYPT_MODE_OFB;
759 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
760 ok(result, "%08x\n", GetLastError());
763 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
764 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
766 CryptDestroyKey(hKey);
769 static void test_3des112(void)
774 unsigned char pbData[16];
777 result = derive_key(CALG_3DES_112, &hKey, 0);
779 /* rsaenh compiled without OpenSSL */
780 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
784 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
787 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
788 ok(result, "%08x\n", GetLastError());
790 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
791 ok(result, "%08x\n", GetLastError());
795 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
797 dwLen = cTestData[i].enclen;
798 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
799 ok(result, "%08x\n", GetLastError());
800 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
802 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
803 ok(result, "%08x\n", GetLastError());
804 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
805 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
806 if((dwLen != cTestData[i].enclen) ||
807 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
809 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
810 printBytes("got",pbData,dwLen);
813 result = CryptDestroyKey(hKey);
814 ok(result, "%08x\n", GetLastError());
817 static void test_des(void)
822 unsigned char pbData[16];
825 result = derive_key(CALG_DES, &hKey, 56);
827 /* rsaenh compiled without OpenSSL */
828 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
832 dwMode = CRYPT_MODE_ECB;
833 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
834 ok(result, "%08x\n", GetLastError());
836 dwLen = sizeof(DWORD);
837 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
838 ok(result, "%08x\n", GetLastError());
840 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
843 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
844 ok(result, "%08x\n", GetLastError());
846 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
847 ok(result, "%08x\n", GetLastError());
851 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
853 dwLen = cTestData[i].enclen;
854 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
855 ok(result, "%08x\n", GetLastError());
856 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
858 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
859 ok(result, "%08x\n", GetLastError());
860 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
861 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
862 if((dwLen != cTestData[i].enclen) ||
863 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
865 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
866 printBytes("got",pbData,dwLen);
870 result = CryptDestroyKey(hKey);
871 ok(result, "%08x\n", GetLastError());
874 static void test_3des(void)
879 unsigned char pbData[16];
880 static const BYTE des3[16] = {
881 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
882 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
885 result = derive_key(CALG_3DES, &hKey, 0);
888 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
891 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
892 ok(result, "%08x\n", GetLastError());
894 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
896 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
897 ok(result, "%08x\n", GetLastError());
901 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
903 dwLen = cTestData[i].enclen;
904 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
905 ok(result, "%08x\n", GetLastError());
906 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
908 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
909 ok(result, "%08x\n", GetLastError());
910 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
911 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
912 if((dwLen != cTestData[i].enclen) ||
913 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
915 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
916 printBytes("got",pbData,dwLen);
919 result = CryptDestroyKey(hKey);
920 ok(result, "%08x\n", GetLastError());
923 static void test_aes(int keylen)
928 unsigned char pbData[16];
934 result = derive_key(CALG_AES_256, &hKey, 0);
937 result = derive_key(CALG_AES_192, &hKey, 0);
941 result = derive_key(CALG_AES_128, &hKey, 0);
946 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
948 /* AES provider doesn't support salt */
949 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
950 ok((!result && GetLastError() == NTE_BAD_KEY) || result /* Win7 */,
951 "expected NTE_BAD_KEY, got %08x\n", GetLastError());
954 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
955 ok(result, "%08x\n", GetLastError());
957 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
958 ok(result, "%08x\n", GetLastError());
962 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
964 dwLen = cTestData[i].enclen;
965 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
966 ok(result, "%08x\n", GetLastError());
967 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
969 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
970 ok(result, "%08x\n", GetLastError());
971 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
972 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
973 if((dwLen != cTestData[i].enclen) ||
974 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
976 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
977 printBytes("got",pbData,dwLen);
980 result = CryptDestroyKey(hKey);
981 ok(result, "%08x\n", GetLastError());
984 static void test_sha2(void)
986 static const unsigned char sha256hash[32] = {
987 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
988 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
989 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
992 static const unsigned char sha384hash[48] = {
993 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
994 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
995 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
996 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
997 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
999 static const unsigned char sha512hash[64] = {
1000 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1001 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1002 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1003 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1004 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1005 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1006 0xb7, 0xf4, 0x81, 0xd4
1008 unsigned char pbData[2048];
1011 BYTE pbHashValue[64];
1015 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1018 SetLastError(0xdeadbeef);
1019 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1020 if (!result && GetLastError() == NTE_BAD_ALGID) {
1021 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1024 ok(result, "%08x\n", GetLastError());
1026 len = sizeof(DWORD);
1027 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1028 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1030 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1031 ok(result, "%08x\n", GetLastError());
1034 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1035 ok(result, "%08x\n", GetLastError());
1037 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1039 result = CryptDestroyHash(hHash);
1040 ok(result, "%08x\n", GetLastError());
1044 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1045 ok(result, "%08x\n", GetLastError());
1047 len = sizeof(DWORD);
1048 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1049 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1051 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1052 ok(result, "%08x\n", GetLastError());
1055 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1056 ok(result, "%08x\n", GetLastError());
1058 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1060 result = CryptDestroyHash(hHash);
1061 ok(result, "%08x\n", GetLastError());
1065 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1066 ok(result, "%08x\n", GetLastError());
1068 len = sizeof(DWORD);
1069 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1070 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1072 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1073 ok(result, "%08x\n", GetLastError());
1076 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1077 ok(result, "%08x\n", GetLastError());
1079 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1081 result = CryptDestroyHash(hHash);
1082 ok(result, "%08x\n", GetLastError());
1086 static void test_rc2(void)
1088 static const BYTE rc2_40_encrypted[16] = {
1089 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1090 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1091 static const BYTE rc2_128_encrypted[] = {
1092 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
1097 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
1099 unsigned char pbData[2000], pbHashValue[16];
1102 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1105 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1107 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1109 CRYPT_INTEGER_BLOB salt;
1111 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1112 ok(result, "%08x\n", GetLastError());
1115 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1116 ok(result, "%08x\n", GetLastError());
1118 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1119 ok(result, "%08x\n", GetLastError());
1121 dwLen = sizeof(DWORD);
1122 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1123 ok(result, "%08x\n", GetLastError());
1125 dwMode = CRYPT_MODE_CBC;
1126 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1127 ok(result, "%08x\n", GetLastError());
1129 dwLen = sizeof(DWORD);
1130 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1131 ok(result, "%08x\n", GetLastError());
1133 dwModeBits = 0xdeadbeef;
1134 dwLen = sizeof(DWORD);
1135 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1136 ok(result, "%08x\n", GetLastError());
1138 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1139 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
1140 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1141 " got %08x\n", dwModeBits);
1143 dwLen = sizeof(DWORD);
1144 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1145 ok(result, "%08x\n", GetLastError());
1147 dwLen = sizeof(DWORD);
1148 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1149 ok(result, "%08x\n", GetLastError());
1151 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1152 ok(result, "%08x\n", GetLastError());
1153 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1154 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1155 HeapFree(GetProcessHeap(), 0, pbTemp);
1157 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1158 ok(result, "%08x\n", GetLastError());
1159 /* The default salt length is always 11... */
1160 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1161 /* and the default salt is always empty. */
1162 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1163 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1164 for (i=0; i<dwLen; i++)
1165 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1166 HeapFree(GetProcessHeap(), 0, pbTemp);
1168 dwLen = sizeof(DWORD);
1169 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1171 result = CryptDestroyHash(hHash);
1172 ok(result, "%08x\n", GetLastError());
1175 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1176 ok(result, "%08x\n", GetLastError());
1178 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1180 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1181 ok(result, "%08x\n", GetLastError());
1182 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1183 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1184 HeapFree(GetProcessHeap(), 0, pbTemp);
1186 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1187 ok(result, "%08x\n", GetLastError());
1189 /* Setting the salt also succeeds... */
1190 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1191 ok(result, "setting salt failed: %08x\n", GetLastError());
1192 /* but the resulting salt length is now zero? */
1194 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1195 ok(result, "%08x\n", GetLastError());
1197 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1198 "unexpected salt length %d\n", dwLen);
1199 /* What sizes salt can I set? */
1200 salt.pbData = pbData;
1201 for (i=0; i<24; i++)
1204 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1205 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1206 /* The returned salt length is the same as the set salt length */
1207 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1208 ok(result, "%08x\n", GetLastError());
1209 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1212 SetLastError(0xdeadbeef);
1213 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1215 broken(result), /* Win9x, WinMe, NT4, W2K */
1216 "%08x\n", GetLastError());
1218 result = CryptDestroyKey(hKey);
1219 ok(result, "%08x\n", GetLastError());
1222 /* Again, but test setting the effective key len */
1223 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1225 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1227 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1229 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1230 ok(result, "%08x\n", GetLastError());
1233 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1234 ok(result, "%08x\n", GetLastError());
1236 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1237 ok(result, "%08x\n", GetLastError());
1239 SetLastError(0xdeadbeef);
1240 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1241 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1243 SetLastError(0xdeadbeef);
1244 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1245 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1247 SetLastError(0xdeadbeef);
1248 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1250 dwLen = sizeof(dwKeyLen);
1251 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1252 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1253 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1254 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1257 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1258 ok(result, "%d\n", GetLastError());
1260 dwLen = sizeof(dwKeyLen);
1261 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1262 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1263 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1264 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1266 result = CryptDestroyHash(hHash);
1267 ok(result, "%08x\n", GetLastError());
1270 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1271 ok(result, "%08x\n", GetLastError());
1273 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1274 "RC2 encryption failed!\n");
1276 /* Oddly enough this succeeds, though it should have no effect */
1278 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1279 ok(result, "%d\n", GetLastError());
1281 result = CryptDestroyKey(hKey);
1282 ok(result, "%08x\n", GetLastError());
1286 static void test_rc4(void)
1288 static const BYTE rc4[16] = {
1289 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1290 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1294 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1295 unsigned char pbData[2000], *pbTemp;
1296 unsigned char pszBuffer[256];
1299 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1302 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1304 /* rsaenh compiled without OpenSSL */
1305 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1307 CRYPT_INTEGER_BLOB salt;
1309 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1310 ok(result, "%08x\n", GetLastError());
1313 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1314 ok(result, "%08x\n", GetLastError());
1316 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1317 ok(result, "%08x\n", GetLastError());
1319 dwLen = sizeof(DWORD);
1320 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1321 ok(result, "%08x\n", GetLastError());
1323 dwLen = sizeof(DWORD);
1324 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1325 ok(result, "%08x\n", GetLastError());
1327 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1328 ok(result, "%08x\n", GetLastError());
1329 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1330 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1331 HeapFree(GetProcessHeap(), 0, pbTemp);
1333 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1334 ok(result, "%08x\n", GetLastError());
1335 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1336 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1337 HeapFree(GetProcessHeap(), 0, pbTemp);
1339 dwLen = sizeof(DWORD);
1340 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1342 result = CryptDestroyHash(hHash);
1343 ok(result, "%08x\n", GetLastError());
1346 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1347 ok(result, "%08x\n", GetLastError());
1349 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1350 ok(result, "%08x\n", GetLastError());
1352 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1354 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1355 ok(result, "%08x\n", GetLastError());
1357 /* Setting the salt also succeeds... */
1358 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1359 ok(result, "setting salt failed: %08x\n", GetLastError());
1360 /* but the resulting salt length is now zero? */
1362 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1363 ok(result, "%08x\n", GetLastError());
1365 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1366 "unexpected salt length %d\n", dwLen);
1367 /* What sizes salt can I set? */
1368 salt.pbData = pbData;
1369 for (i=0; i<24; i++)
1372 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1373 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1374 /* The returned salt length is the same as the set salt length */
1375 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1376 ok(result, "%08x\n", GetLastError());
1377 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1380 SetLastError(0xdeadbeef);
1381 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1383 broken(result), /* Win9x, WinMe, NT4, W2K */
1384 "%08x\n", GetLastError());
1386 result = CryptDestroyKey(hKey);
1387 ok(result, "%08x\n", GetLastError());
1391 static void test_hmac(void) {
1395 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1396 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1399 static const BYTE hmac[16] = {
1400 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1401 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1404 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1406 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1408 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1409 ok(result, "%08x\n", GetLastError());
1410 if (!result) return;
1412 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1413 ok(result, "%08x\n", GetLastError());
1415 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1416 ok(result, "%08x\n", GetLastError());
1418 dwLen = sizeof(abData)/sizeof(BYTE);
1419 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1420 ok(result, "%08x\n", GetLastError());
1422 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1424 result = CryptDestroyHash(hHash);
1425 ok(result, "%08x\n", GetLastError());
1427 result = CryptDestroyKey(hKey);
1428 ok(result, "%08x\n", GetLastError());
1430 /* Provoke errors */
1431 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1432 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1435 static void test_mac(void) {
1440 BYTE abData[256], abEnc[264];
1441 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1444 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1445 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1447 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1450 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1451 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1453 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1454 ok(result, "%08x\n", GetLastError());
1455 if (!result) return;
1457 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1458 ok(result, "%08x\n", GetLastError());
1460 dwLen = sizeof(abData)/sizeof(BYTE);
1461 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1462 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1464 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1466 result = CryptDestroyHash(hHash);
1467 ok(result, "%08x\n", GetLastError());
1469 result = CryptDestroyKey(hKey);
1470 ok(result, "%08x\n", GetLastError());
1472 /* Provoke errors */
1473 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1475 SetLastError(0xdeadbeef);
1476 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1477 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1478 broken(result), /* Win9x, WinMe, NT4, W2K */
1479 "%08x\n", GetLastError());
1481 result = CryptDestroyKey(hKey);
1482 ok(result, "%08x\n", GetLastError());
1485 static void test_import_private(void)
1488 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1490 static BYTE abSessionKey[148] = {
1491 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1492 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1493 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1494 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1495 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1496 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1497 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1498 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1499 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1500 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1501 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1502 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1503 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1504 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1505 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1506 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1507 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1508 0x04, 0x8c, 0x49, 0x92
1510 static BYTE abEncryptedMessage[12] = {
1511 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1512 0x1c, 0xfd, 0xde, 0x71
1515 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1516 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1518 /* rsaenh compiled without OpenSSL */
1519 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1523 dwLen = (DWORD)sizeof(abSessionKey);
1524 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1525 ok(result, "%08x\n", GetLastError());
1526 if (!result) return;
1529 dwLen = sizeof(DWORD);
1530 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1531 ok(result, "%08x\n", GetLastError());
1533 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1534 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1535 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1536 " got %08x\n", dwVal);
1538 dwLen = (DWORD)sizeof(abEncryptedMessage);
1539 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1540 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1541 "%08x, len: %d\n", GetLastError(), dwLen);
1542 CryptDestroyKey(hSessionKey);
1544 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1546 dwLen = (DWORD)sizeof(abSessionKey);
1547 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1548 ok(result, "%08x\n", GetLastError());
1549 CryptDestroyKey(hSessionKey);
1550 if (!result) return;
1552 dwLen = (DWORD)sizeof(abSessionKey);
1553 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1554 ok(result, "%08x\n", GetLastError());
1555 if (!result) return;
1557 CryptDestroyKey(hSessionKey);
1558 CryptDestroyKey(hKeyExchangeKey);
1561 static void test_verify_signature(void) {
1563 HCRYPTKEY hPubSignKey;
1564 BYTE abData[] = "Wine rocks!";
1566 BYTE abPubKey[148] = {
1567 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1568 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1569 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1570 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1571 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1572 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1573 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1574 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1575 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1576 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1577 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1578 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1579 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1580 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1581 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1582 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1583 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1584 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1585 0xe1, 0x21, 0x50, 0xac
1587 /* md2 with hash oid */
1588 BYTE abSignatureMD2[128] = {
1589 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1590 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1591 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1592 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1593 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1594 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1595 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1596 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1597 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1598 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1599 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1600 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1601 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1602 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1603 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1604 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1606 /* md2 without hash oid */
1607 BYTE abSignatureMD2NoOID[128] = {
1608 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1609 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1610 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1611 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1612 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1613 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1614 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1615 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1616 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1617 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1618 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1619 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1620 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1621 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1622 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1623 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1625 /* md4 with hash oid */
1626 BYTE abSignatureMD4[128] = {
1627 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1628 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1629 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1630 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1631 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1632 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1633 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1634 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1635 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1636 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1637 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1638 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1639 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1640 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1641 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1642 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1644 /* md4 without hash oid */
1645 BYTE abSignatureMD4NoOID[128] = {
1646 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1647 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1648 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1649 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1650 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1651 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1652 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1653 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1654 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1655 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1656 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1657 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1658 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1659 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1660 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1661 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1663 /* md5 with hash oid */
1664 BYTE abSignatureMD5[128] = {
1665 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1666 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1667 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1668 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1669 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1670 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1671 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1672 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1673 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1674 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1675 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1676 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1677 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1678 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1679 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1680 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1682 /* md5 without hash oid */
1683 BYTE abSignatureMD5NoOID[128] = {
1684 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1685 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1686 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1687 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1688 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1689 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1690 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1691 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1692 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1693 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1694 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1695 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1696 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1697 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1698 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1699 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1701 /* sha with hash oid */
1702 BYTE abSignatureSHA[128] = {
1703 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1704 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1705 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1706 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1707 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1708 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1709 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1710 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1711 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1712 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1713 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1714 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1715 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1716 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1717 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1718 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1720 /* sha without hash oid */
1721 BYTE abSignatureSHANoOID[128] = {
1722 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1723 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1724 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1725 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1726 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1727 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1728 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1729 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1730 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1731 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1732 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1733 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1734 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1735 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1736 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1737 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1740 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1741 ok(result, "%08x\n", GetLastError());
1742 if (!result) return;
1744 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1745 ok(result, "%08x\n", GetLastError());
1746 if (!result) return;
1748 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1749 ok(result, "%08x\n", GetLastError());
1750 if (!result) return;
1752 /*check that a NULL pointer signature is correctly handled*/
1753 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1754 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1755 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1758 /* check that we get a bad signature error when the signature is too short*/
1759 SetLastError(0xdeadbeef);
1760 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1761 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1762 broken(result), /* Win9x, WinMe, NT4 */
1763 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1765 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1766 ok(result, "%08x\n", GetLastError());
1767 if (!result) return;
1769 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1770 ok(result, "%08x\n", GetLastError());
1771 if (!result) return;
1773 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1774 * the OID at all. */
1775 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1776 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1777 if (result) return;*/
1779 CryptDestroyHash(hHash);
1781 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1782 ok(result, "%08x\n", GetLastError());
1783 if (!result) return;
1785 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1786 ok(result, "%08x\n", GetLastError());
1787 if (!result) return;
1789 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1790 ok(result, "%08x\n", GetLastError());
1791 if (!result) return;
1793 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1794 ok(result, "%08x\n", GetLastError());
1795 if (!result) return;
1797 CryptDestroyHash(hHash);
1799 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1800 ok(result, "%08x\n", GetLastError());
1801 if (!result) return;
1803 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1804 ok(result, "%08x\n", GetLastError());
1805 if (!result) return;
1807 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1808 ok(result, "%08x\n", GetLastError());
1809 if (!result) return;
1811 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1812 ok(result, "%08x\n", GetLastError());
1813 if (!result) return;
1815 CryptDestroyHash(hHash);
1817 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1818 ok(result, "%08x\n", GetLastError());
1819 if (!result) return;
1821 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1822 ok(result, "%08x\n", GetLastError());
1823 if (!result) return;
1825 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1826 ok(result, "%08x\n", GetLastError());
1827 if (!result) return;
1829 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1830 ok(result, "%08x\n", GetLastError());
1831 if (!result) return;
1833 CryptDestroyHash(hHash);
1834 CryptDestroyKey(hPubSignKey);
1837 static void test_rsa_encrypt(void)
1840 BYTE abData[2048] = "Wine rocks!";
1844 /* It is allowed to use the key exchange key for encryption/decryption */
1845 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1846 ok (result, "%08x\n", GetLastError());
1847 if (!result) return;
1850 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1851 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1852 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1854 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1855 ok (result, "%08x\n", GetLastError());
1856 if (!result) return;
1858 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1859 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1862 dwLen = sizeof(DWORD);
1863 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1864 ok(result, "%08x\n", GetLastError());
1866 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1867 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1868 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1869 " got %08x\n", dwVal);
1871 /* An RSA key doesn't support salt */
1872 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1873 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
1874 "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
1876 /* The key exchange key's public key may be exported.. */
1877 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1878 ok(result, "%08x\n", GetLastError());
1879 /* but its private key may not be. */
1880 SetLastError(0xdeadbeef);
1881 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1882 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1883 broken(result), /* Win9x/NT4 */
1884 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1885 /* Setting the permissions of the key exchange key isn't allowed, either. */
1886 dwVal |= CRYPT_EXPORT;
1887 SetLastError(0xdeadbeef);
1888 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1890 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1891 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1893 CryptDestroyKey(hRSAKey);
1895 /* It is not allowed to use the signature key for encryption/decryption */
1896 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1897 ok (result, "%08x\n", GetLastError());
1898 if (!result) return;
1901 dwLen = sizeof(DWORD);
1902 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1903 ok(result, "%08x\n", GetLastError());
1905 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1906 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1907 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1908 " got %08x\n", dwVal);
1910 /* The signature key's public key may also be exported.. */
1911 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1912 ok(result, "%08x\n", GetLastError());
1913 /* but its private key may not be. */
1914 SetLastError(0xdeadbeef);
1915 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1916 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1917 broken(result), /* Win9x/NT4 */
1918 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1919 /* Setting the permissions of the signature key isn't allowed, either. */
1920 dwVal |= CRYPT_EXPORT;
1921 SetLastError(0xdeadbeef);
1922 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1924 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1925 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1928 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1929 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1931 CryptDestroyKey(hRSAKey);
1934 static void test_import_export(void)
1936 DWORD dwLen, dwDataLen, dwVal;
1937 HCRYPTKEY hPublicKey, hPrivKey;
1940 BYTE emptyKey[2048], *exported_key;
1941 static BYTE abPlainPublicKey[84] = {
1942 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1943 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1944 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1945 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1946 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1947 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1948 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1949 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1950 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1951 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1952 0x11, 0x11, 0x11, 0x11
1954 static BYTE priv_key_with_high_bit[] = {
1955 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1956 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1957 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1958 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1959 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1960 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1961 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1962 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1963 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1964 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1965 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1966 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1967 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1968 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1969 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1970 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1971 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1972 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1973 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1974 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1975 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1976 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1977 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1978 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1979 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1980 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1981 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1982 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1983 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1984 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1985 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1986 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1987 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1988 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1989 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1990 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1991 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1992 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1993 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1994 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1995 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1996 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1997 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1998 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1999 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2000 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2001 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2002 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2003 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2004 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2005 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2006 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2007 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2008 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2009 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2010 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2011 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2012 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2013 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2014 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2015 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2016 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2017 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2018 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2019 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2020 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2021 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2022 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2023 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2024 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2025 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2026 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2027 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2028 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2029 0xb6, 0x5f, 0x01, 0x5e
2031 static const BYTE expected_exported_priv_key[] = {
2032 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2033 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2034 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2035 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2036 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2037 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2038 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2039 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2040 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2041 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2042 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2043 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2044 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2045 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2046 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2047 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2048 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2049 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2050 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2051 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2052 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2053 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2054 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2055 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2056 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2057 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2058 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2059 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2060 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2061 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2062 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2063 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2064 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2065 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2066 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2067 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2068 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2069 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2070 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2071 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2072 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2073 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2074 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2075 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2076 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2077 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2078 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2079 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2080 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2081 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2082 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2083 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2084 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2085 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2086 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2087 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2088 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2089 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2090 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2091 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2092 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2093 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2094 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2095 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2096 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2097 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2098 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2099 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2100 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2101 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2102 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2103 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2104 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2105 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2106 0xb6, 0x5f, 0x01, 0x5e
2110 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2111 ok(result, "failed to import the public key\n");
2113 dwDataLen=sizeof(algID);
2114 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2115 ok(result, "failed to get the KP_ALGID from the imported public key\n");
2116 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2119 dwDataLen = sizeof(DWORD);
2120 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2121 ok(result, "%08x\n", GetLastError());
2123 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2124 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2125 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2126 " got %08x\n", dwVal);
2127 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2128 ok(result, "failed to export the fresh imported public key\n");
2129 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2130 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2132 CryptDestroyKey(hPublicKey);
2134 result = CryptImportKey(hProv, priv_key_with_high_bit,
2135 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2136 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2138 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2139 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2140 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2141 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2143 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2145 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2147 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2148 "unexpected value\n");
2150 HeapFree(GetProcessHeap(), 0, exported_key);
2152 CryptDestroyKey(hPrivKey);
2155 static void test_import_hmac(void)
2157 /* Test cases from RFC 2202, section 3 */
2158 static const struct rfc2202_test_case {
2162 const DWORD data_len;
2165 { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2166 "\x0b\x0b\x0b\x0b", 20,
2168 "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2169 "\xf1\x46\xbe\x00" },
2171 "what do ya want for nothing?", 28,
2172 "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2173 "\x25\x9a\x7c\x79" },
2174 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2175 "\xaa\xaa\xaa\xaa", 20,
2176 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2177 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2178 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2180 "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2181 "\x63\xf1\x75\xd3" },
2182 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2183 "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2184 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2185 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2186 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2188 "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2189 "\x2d\x72\x35\xda" },
2190 { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2191 "\x0c\x0c\x0c\x0c", 20,
2192 "Test With Truncation", 20,
2193 "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2194 "\x4a\x9a\x5a\x04" },
2195 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2196 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2197 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2198 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2199 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2201 "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2202 "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2203 "\xed\x40\x21\x12" },
2204 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2205 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2206 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2207 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2208 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2210 "Test Using Larger Than Block-Size Key and Larger "
2211 "Than One Block-Size Data", 73,
2212 "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2213 "\xbb\xff\x1a\x91" }
2217 for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++)
2219 const struct rfc2202_test_case *test_case = &cases[i];
2220 DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2221 BYTE *blob = HeapAlloc(GetProcessHeap(), 0, size);
2225 BLOBHEADER *header = (BLOBHEADER *)blob;
2226 DWORD *key_len = (DWORD *)(header + 1);
2227 BYTE *key_bytes = (BYTE *)(key_len + 1);
2231 header->bType = PLAINTEXTKEYBLOB;
2232 header->bVersion = CUR_BLOB_VERSION;
2233 header->reserved = 0;
2234 header->aiKeyAlg = CALG_RC2;
2235 *key_len = test_case->key_len;
2236 memcpy(key_bytes, test_case->key, *key_len);
2237 result = CryptImportKey(hProv, blob, size, 0, CRYPT_IPSEC_HMAC_KEY, &key);
2239 ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
2243 HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2247 result = CryptCreateHash(hProv, CALG_HMAC, key, 0, &hash);
2248 ok(result, "CryptCreateHash failed on test case %d: %08x\n", i, GetLastError());
2249 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2250 ok(result, "CryptSetHashParam failed on test case %d: %08x\n", i, GetLastError());
2251 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2252 ok(result, "CryptHashData failed on test case %d: %08x\n", i, GetLastError());
2253 digest_size = sizeof(digest);
2254 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2255 ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
2256 ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected valued on test case %d\n", i);
2257 CryptDestroyHash(hash);
2258 CryptDestroyKey(key);
2260 HeapFree(GetProcessHeap(), 0, blob);
2265 static void test_schannel_provider(void)
2268 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2269 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2272 SCHANNEL_ALG saSChannelAlg;
2273 CRYPT_DATA_BLOB data_blob;
2274 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2275 BYTE abTLS1Master[140] = {
2276 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2277 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2278 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2279 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2280 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2281 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2282 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2283 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2284 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2285 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2286 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2287 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2288 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2289 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2290 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2291 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2292 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2293 0xd3, 0x1e, 0x82, 0xb3
2295 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2296 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2297 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2298 BYTE abClientFinished[16] = "client finished";
2299 BYTE abData[16] = "Wine rocks!";
2301 static const BYTE abEncryptedData[16] = {
2302 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2303 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2305 static const BYTE abPRF[16] = {
2306 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2307 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2309 static const BYTE abMD5[16] = {
2310 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2311 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2314 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2317 win_skip("no PROV_RSA_SCHANNEL support\n");
2320 ok (result, "%08x\n", GetLastError());
2322 CryptReleaseContext(hProv, 0);
2324 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2325 ok (result, "%08x\n", GetLastError());
2326 if (!result) return;
2328 /* To get deterministic results, we import the TLS1 master secret (which
2329 * is typically generated from a random generator). Therefore, we need
2331 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2332 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2333 ok (result, "%08x\n", GetLastError());
2334 if (!result) return;
2336 dwLen = (DWORD)sizeof(abTLS1Master);
2337 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2338 ok (result, "%08x\n", GetLastError());
2339 if (!result) return;
2341 /* Setting the TLS1 client and server random parameters, as well as the
2342 * MAC and encryption algorithm parameters. */
2343 data_blob.cbData = 33;
2344 data_blob.pbData = abClientSecret;
2345 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2346 ok (result, "%08x\n", GetLastError());
2347 if (!result) return;
2349 data_blob.cbData = 33;
2350 data_blob.pbData = abServerSecret;
2351 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2352 ok (result, "%08x\n", GetLastError());
2353 if (!result) return;
2355 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2356 saSChannelAlg.Algid = CALG_DES;
2357 saSChannelAlg.cBits = 64;
2358 saSChannelAlg.dwFlags = 0;
2359 saSChannelAlg.dwReserved = 0;
2360 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2361 ok (result, "%08x\n", GetLastError());
2362 if (!result) return;
2364 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2365 saSChannelAlg.Algid = CALG_MD5;
2366 saSChannelAlg.cBits = 128;
2367 saSChannelAlg.dwFlags = 0;
2368 saSChannelAlg.dwReserved = 0;
2369 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2370 ok (result, "%08x\n", GetLastError());
2371 if (!result) return;
2373 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2374 * (Keys can only be derived from hashes, not from other keys.) */
2375 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2376 ok (result, "%08x\n", GetLastError());
2377 if (!result) return;
2379 /* Deriving the server write encryption key from the master hash */
2380 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2381 ok (result, "%08x\n", GetLastError());
2382 if (!result) return;
2384 /* Encrypting some data with the server write encryption key and checking the result. */
2386 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2387 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2389 /* Second test case: Test the TLS1 pseudo random number function. */
2390 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2391 ok (result, "%08x\n", GetLastError());
2392 if (!result) return;
2394 /* Set the label and seed parameters for the random number function */
2395 data_blob.cbData = 36;
2396 data_blob.pbData = abHashedHandshakes;
2397 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2398 ok (result, "%08x\n", GetLastError());
2399 if (!result) return;
2401 data_blob.cbData = 15;
2402 data_blob.pbData = abClientFinished;
2403 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2404 ok (result, "%08x\n", GetLastError());
2405 if (!result) return;
2407 /* Generate some pseudo random bytes and check if they are correct. */
2408 dwLen = (DWORD)sizeof(abData);
2409 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2410 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2411 "%08x\n", GetLastError());
2413 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2414 * Hash some data with the HMAC. Compare results. */
2415 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2416 ok (result, "%08x\n", GetLastError());
2417 if (!result) return;
2419 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2420 ok (result, "%08x\n", GetLastError());
2421 if (!result) return;
2423 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2424 ok (result, "%08x\n", GetLastError());
2425 if (!result) return;
2427 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2428 ok (result, "%08x\n", GetLastError());
2429 if (!result) return;
2431 dwLen = (DWORD)sizeof(abMD5Hash);
2432 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2433 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2435 CryptDestroyHash(hHMAC);
2436 CryptDestroyHash(hTLS1PRF);
2437 CryptDestroyHash(hMasterHash);
2438 CryptDestroyKey(hServerWriteMACKey);
2439 CryptDestroyKey(hServerWriteKey);
2440 CryptDestroyKey(hRSAKey);
2441 CryptDestroyKey(hMasterSecret);
2442 CryptReleaseContext(hProv, 0);
2443 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2446 /* Test that a key can be used to encrypt data and exported, and that, when
2447 * the exported key is imported again, can be used to decrypt the original
2450 static void test_rsa_round_trip(void)
2452 static const char test_string[] = "Well this is a fine how-do-you-do.";
2454 HCRYPTKEY signKey, keyExchangeKey;
2456 BYTE data[256], *exportedKey;
2457 DWORD dataLen, keyLen;
2459 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2460 CRYPT_DELETEKEYSET);
2462 /* Generate a new key... */
2463 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2465 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2466 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2467 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2468 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2469 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2470 /* encrypt some data with it... */
2471 memcpy(data, test_string, strlen(test_string) + 1);
2472 dataLen = strlen(test_string) + 1;
2473 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2475 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2476 broken(GetLastError() == NTE_PERM /* NT4 */),
2477 "CryptEncrypt failed: %08x\n", GetLastError());
2478 /* export the key... */
2479 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2481 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2482 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2483 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2485 /* destroy the key... */
2486 CryptDestroyKey(keyExchangeKey);
2487 CryptDestroyKey(signKey);
2488 /* import the key again... */
2489 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2490 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2491 HeapFree(GetProcessHeap(), 0, exportedKey);
2492 /* and decrypt the data encrypted with the original key with the imported
2495 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2496 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2497 broken(GetLastError() == NTE_PERM /* NT4 */),
2498 "CryptDecrypt failed: %08x\n", GetLastError());
2501 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2502 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2504 CryptDestroyKey(keyExchangeKey);
2505 CryptReleaseContext(prov, 0);
2507 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2508 CRYPT_DELETEKEYSET);
2511 static void test_enum_container(void)
2513 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2515 BOOL result, fFound = FALSE;
2517 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2518 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2519 SetLastError(0xdeadbeef);
2520 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2521 ok (result, "%08x\n", GetLastError());
2522 ok (dwBufferLen == MAX_PATH + 1 ||
2523 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2524 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2526 /* If the result fits into abContainerName dwBufferLen is left untouched */
2527 dwBufferLen = (DWORD)sizeof(abContainerName);
2528 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2529 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2531 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2533 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2534 dwBufferLen = (DWORD)sizeof(abContainerName);
2535 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2537 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2540 static BYTE signBlob[] = {
2541 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2542 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2543 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2544 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2545 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2546 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2547 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2548 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2549 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2550 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2551 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2552 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2553 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2554 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2555 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2556 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2557 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2558 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2559 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2560 0xb6,0x85,0x86,0x07 };
2562 static void test_null_provider(void)
2567 DWORD keySpec, dataLen,dwParam;
2568 char szName[MAX_PATH];
2570 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2571 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2572 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2573 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2574 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2575 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2576 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2577 CRYPT_DELETEKEYSET);
2578 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2579 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2580 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2581 CRYPT_DELETEKEYSET);
2582 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2583 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2584 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2585 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2586 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2588 /* Delete the default container. */
2589 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2590 /* Once you've deleted the default container you can't open it as if it
2593 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2594 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2595 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2596 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2597 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2598 CRYPT_VERIFYCONTEXT);
2599 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2600 if (!result) return;
2601 dataLen = sizeof(keySpec);
2602 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2604 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2605 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2606 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2607 * supported, you can't get the keys from this container.
2609 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2610 ok(!result && GetLastError() == NTE_NO_KEY,
2611 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2612 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2613 ok(!result && GetLastError() == NTE_NO_KEY,
2614 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2615 result = CryptReleaseContext(prov, 0);
2616 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2617 /* You can create a new default container. */
2618 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2620 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2621 /* But you still can't get the keys (until one's been generated.) */
2622 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2623 ok(!result && GetLastError() == NTE_NO_KEY,
2624 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2625 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2626 ok(!result && GetLastError() == NTE_NO_KEY,
2627 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2628 CryptReleaseContext(prov, 0);
2629 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2631 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2632 CRYPT_DELETEKEYSET);
2633 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2634 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2635 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2636 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2637 CRYPT_VERIFYCONTEXT);
2638 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2639 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2640 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2642 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2643 if (!result) return;
2644 /* Test provider parameters getter */
2645 dataLen = sizeof(dwParam);
2646 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2647 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2648 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2649 dataLen = sizeof(dwParam);
2650 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2651 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2652 "Expected 0, got 0x%08X\n",dwParam);
2653 dataLen = sizeof(dwParam);
2654 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2655 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2656 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2657 dataLen = sizeof(keySpec);
2658 SetLastError(0xdeadbeef);
2659 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2660 if (!result && GetLastError() == NTE_BAD_TYPE)
2661 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2663 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2664 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2665 /* PP_CONTAINER parameter */
2666 dataLen = sizeof(szName);
2667 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2668 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2669 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2670 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2671 /* PP_UNIQUE_CONTAINER parameter */
2672 dataLen = sizeof(szName);
2673 SetLastError(0xdeadbeef);
2674 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2675 if (!result && GetLastError() == NTE_BAD_TYPE)
2677 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2681 char container[MAX_PATH];
2683 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2684 uniquecontainer(container);
2687 ok(dataLen == strlen(container)+1 ||
2688 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2689 "Expected a param length of 70, got %d\n", dataLen);
2690 ok(!strcmp(container, szName) ||
2691 broken(!strcmp(szName, szContainer)) /* WinME */,
2692 "Wrong container name : %s\n", szName);
2695 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2696 ok(!result && GetLastError() == NTE_NO_KEY,
2697 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2698 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2699 ok(!result && GetLastError() == NTE_NO_KEY,
2700 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2702 /* Importing a key exchange blob.. */
2703 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2705 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2706 CryptDestroyKey(key);
2707 /* allows access to the key exchange key.. */
2708 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2709 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2710 CryptDestroyKey(key);
2711 /* but not to the private key. */
2712 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2713 ok(!result && GetLastError() == NTE_NO_KEY,
2714 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2715 CryptReleaseContext(prov, 0);
2716 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2717 CRYPT_DELETEKEYSET);
2719 /* Whereas importing a sign blob.. */
2720 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2722 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2723 if (!result) return;
2724 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2725 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2726 CryptDestroyKey(key);
2727 /* doesn't allow access to the key exchange key.. */
2728 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2729 ok(!result && GetLastError() == NTE_NO_KEY,
2730 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2731 /* but does to the private key. */
2732 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2733 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2734 CryptDestroyKey(key);
2735 CryptReleaseContext(prov, 0);
2737 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2738 CRYPT_DELETEKEYSET);
2740 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2741 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2743 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2744 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2745 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2746 CryptDestroyKey(key);
2747 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2748 ok(!result, "expected CryptGetUserKey to fail\n");
2749 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2750 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2751 CryptDestroyKey(key);
2752 CryptReleaseContext(prov, 0);
2754 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2755 CRYPT_DELETEKEYSET);
2757 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2758 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2760 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2761 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2762 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2763 CryptDestroyKey(key);
2764 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2765 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2766 CryptDestroyKey(key);
2767 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2768 ok(!result, "expected CryptGetUserKey to fail\n");
2769 CryptReleaseContext(prov, 0);
2771 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2772 CRYPT_DELETEKEYSET);
2774 /* test for the bug in accessing the user key in a container
2776 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2778 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2779 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2780 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2781 CryptDestroyKey(key);
2782 CryptReleaseContext(prov,0);
2783 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2784 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2785 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2786 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2787 CryptDestroyKey(key);
2788 CryptReleaseContext(prov, 0);
2790 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2791 CRYPT_DELETEKEYSET);
2793 /* test the machine key set */
2794 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2795 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2796 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2797 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2798 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2799 CryptReleaseContext(prov, 0);
2800 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2801 CRYPT_MACHINE_KEYSET);
2802 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2803 CryptReleaseContext(prov,0);
2804 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2805 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2806 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2808 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2809 CRYPT_MACHINE_KEYSET);
2810 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2811 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2815 static void test_key_permissions(void)
2817 HCRYPTKEY hKey1, hKey2;
2821 /* Create keys that are exportable */
2822 if (!init_base_environment(CRYPT_EXPORTABLE))
2825 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2826 ok (result, "%08x\n", GetLastError());
2827 if (!result) return;
2830 dwLen = sizeof(DWORD);
2831 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2832 ok(result, "%08x\n", GetLastError());
2834 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2835 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2836 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2837 " got %08x\n", dwVal);
2839 /* The key exchange key's public key may be exported.. */
2840 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2841 ok(result, "%08x\n", GetLastError());
2842 /* and its private key may be too. */
2843 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2844 ok(result, "%08x\n", GetLastError());
2845 /* Turning off the key's export permissions is "allowed".. */
2846 dwVal &= ~CRYPT_EXPORT;
2847 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2849 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2850 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2851 "%08x\n", GetLastError());
2852 /* but it has no effect. */
2854 dwLen = sizeof(DWORD);
2855 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2856 ok(result, "%08x\n", GetLastError());
2858 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2859 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2860 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2861 " got %08x\n", dwVal);
2862 /* Thus, changing the export flag of the key doesn't affect whether the key
2865 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2866 ok(result, "%08x\n", GetLastError());
2868 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2869 ok (result, "%08x\n", GetLastError());
2871 /* A subsequent get of the same key, into a different handle, also doesn't
2872 * show that the permissions have been changed.
2875 dwLen = sizeof(DWORD);
2876 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2877 ok(result, "%08x\n", GetLastError());
2879 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2880 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2881 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2882 " got %08x\n", dwVal);
2884 CryptDestroyKey(hKey2);
2885 CryptDestroyKey(hKey1);
2887 clean_up_base_environment();
2890 static void test_key_initialization(void)
2893 HCRYPTPROV prov1, prov2;
2894 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2896 static BYTE abSessionKey[148] = {
2897 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2898 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2899 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2900 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2901 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2902 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2903 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2904 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2905 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2906 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2907 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2908 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2909 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2910 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2911 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2912 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2913 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2914 0x04, 0x8c, 0x49, 0x92
2917 /* Like init_base_environment, but doesn't generate new keys, as they'll
2918 * be imported instead.
2920 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2922 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2924 ok(result, "%08x\n", GetLastError());
2926 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2927 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2929 dwLen = (DWORD)sizeof(abSessionKey);
2930 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2931 ok(result, "%08x\n", GetLastError());
2933 /* Once the key has been imported, subsequently acquiring a context with
2934 * the same name will allow retrieving the key.
2936 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2937 ok(result, "%08x\n", GetLastError());
2938 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2939 ok(result, "%08x\n", GetLastError());
2940 if (result) CryptDestroyKey(hKey);
2941 CryptReleaseContext(prov2, 0);
2943 CryptDestroyKey(hSessionKey);
2944 CryptDestroyKey(hKeyExchangeKey);
2945 CryptReleaseContext(prov1, 0);
2946 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2947 CRYPT_DELETEKEYSET);
2952 if (!init_base_environment(0))
2964 test_block_cipher_modes();
2965 test_import_private();
2966 test_verify_signature();
2968 test_import_export();
2970 test_enum_container();
2971 clean_up_base_environment();
2972 test_key_permissions();
2973 test_key_initialization();
2974 test_schannel_provider();
2975 test_null_provider();
2976 test_rsa_round_trip();
2977 if (!init_aes_environment())
2983 clean_up_aes_environment();