2 * Unit tests for rsaenh functions
4 * Copyright (c) 2004 Michael Jung
5 * Copyright (c) 2006 Juan Lang
6 * Copyright (c) 2007 Vijay Kiran Kamuju
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
32 static HCRYPTPROV hProv;
33 static const char szContainer[] = "winetest";
34 static const char szProvider[] = MS_ENHANCED_PROV_A;
36 typedef struct _ctdatatype {
37 unsigned char origstr[32];
38 unsigned char decstr[32];
44 static const cryptdata cTestData[4] = {
46 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
49 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
52 {'a','b','c','d','e','f','g','h',0},
55 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
60 * 1. Take the MD5 Hash of the container name (with an extra null byte)
61 * 2. Turn the hash into a 4 DWORD hex value
63 * 4. Add the MachineGuid
66 static void uniquecontainer(char *unique)
68 /* MD5 hash of "winetest\0" in 4 DWORD hex */
69 static const char szContainer_md5[] = "9d20fd8d05ed2b8455d125d0bf6d6a70";
70 static const char szCryptography[] = "Software\\Microsoft\\Cryptography";
71 static const char szMachineGuid[] = "MachineGuid";
74 DWORD size = MAX_PATH;
77 /* Get the MachineGUID */
78 ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szCryptography, 0, KEY_READ | KEY_WOW64_64KEY, &hkey);
79 if (ret == ERROR_ACCESS_DENIED)
81 /* Windows 2000 can't handle KEY_WOW64_64KEY */
82 RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
84 RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
87 lstrcpy(unique, szContainer_md5);
89 lstrcat(unique, guid);
92 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
95 printf("%s: ",heading);
97 printf("0x%02x,",pb[i]);
101 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
104 static void trace_hex(BYTE *pbData, DWORD dwLen) {
108 for (i = 0; i < dwLen-7; i+=8) {
109 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
110 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
111 pbData[i+6], pbData[i+7]);
114 for (j=0; i<dwLen; j++,i++) {
115 sprintf(szTemp+6*j, "0x%02x,\n", pbData[i]);
121 static int init_base_environment(DWORD dwKeyFlags)
126 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
128 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
130 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
131 ok(!result && (GetLastError()==NTE_BAD_FLAGS ||
132 broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */)),
133 "%d, %08x\n", result, GetLastError());
135 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
137 ok(GetLastError()==NTE_BAD_KEYSET ||
138 broken(GetLastError() == NTE_TEMPORARY_PROFILE /* some Win7 setups */) ||
139 broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */),
140 "%08x\n", GetLastError());
141 if (GetLastError()!=NTE_BAD_KEYSET)
143 win_skip("RSA full provider not available\n");
146 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
148 ok(result, "%08x\n", GetLastError());
151 win_skip("Couldn't create crypto provider\n");
154 result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey);
155 ok(result, "%08x\n", GetLastError());
156 if (result) CryptDestroyKey(hKey);
157 result = CryptGenKey(hProv, AT_SIGNATURE, dwKeyFlags, &hKey);
158 ok(result, "%08x\n", GetLastError());
159 if (result) CryptDestroyKey(hKey);
164 static void clean_up_base_environment(void)
168 SetLastError(0xdeadbeef);
169 result = CryptReleaseContext(hProv, 1);
170 ok(!result || broken(result) /* Win98 */, "Expected failure\n");
171 ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
173 /* Just to prove that Win98 also released the CSP */
174 SetLastError(0xdeadbeef);
175 result = CryptReleaseContext(hProv, 0);
176 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
178 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
181 static int init_aes_environment(void)
186 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
188 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
190 /* we are using NULL as provider name for RSA_AES provider as the provider
191 * names are different in Windows XP and Vista. Its different as to what
192 * its defined in the SDK on Windows XP.
193 * This provider is available on Windows XP, Windows 2003 and Vista. */
195 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
196 if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
198 win_skip("RSA_AES provider not supported\n");
201 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
203 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
205 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
206 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
207 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
209 ok(result, "%08x\n", GetLastError());
210 if (!result) return 0;
211 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
212 ok(result, "%08x\n", GetLastError());
213 if (result) CryptDestroyKey(hKey);
214 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
215 ok(result, "%08x\n", GetLastError());
216 if (result) CryptDestroyKey(hKey);
221 static void clean_up_aes_environment(void)
225 result = CryptReleaseContext(hProv, 1);
226 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
228 CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
231 static void test_prov(void)
236 dwLen = (DWORD)sizeof(DWORD);
237 SetLastError(0xdeadbeef);
238 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
239 if (!result && GetLastError() == NTE_BAD_TYPE)
240 skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
242 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
244 dwLen = (DWORD)sizeof(DWORD);
245 SetLastError(0xdeadbeef);
246 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
247 if (!result && GetLastError() == NTE_BAD_TYPE)
248 skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
250 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
253 static void test_gen_random(void)
256 BYTE rnd1[16], rnd2[16];
258 memset(rnd1, 0, sizeof(rnd1));
259 memset(rnd2, 0, sizeof(rnd2));
261 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
262 if (!result && GetLastError() == NTE_FAIL) {
263 /* rsaenh compiled without OpenSSL */
267 ok(result, "%08x\n", GetLastError());
269 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
270 ok(result, "%08x\n", GetLastError());
272 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
275 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
279 unsigned char pbData[2000];
283 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
284 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
286 /* rsaenh compiled without OpenSSL */
287 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
290 ok(result, "%08x\n", GetLastError());
291 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
292 ok(result, "%08x\n", GetLastError());
293 if (!result) return FALSE;
294 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
295 ok(result, "%08x\n", GetLastError());
296 if (!result) return FALSE;
298 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
299 ok(result, "%08x\n", GetLastError());
300 CryptDestroyHash(hHash);
304 static BYTE abPlainPrivateKey[596] = {
305 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
306 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
307 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
308 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
309 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
310 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
311 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
312 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
313 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
314 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
315 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
316 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
317 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
318 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
319 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
320 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
321 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
322 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
323 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
324 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
325 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
326 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
327 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
328 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
329 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
330 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
331 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
332 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
333 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
334 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
335 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
336 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
337 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
338 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
339 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
340 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
341 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
342 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
343 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
344 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
345 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
346 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
347 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
348 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
349 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
350 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
351 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
352 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
353 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
354 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
355 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
356 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
357 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
358 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
359 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
360 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
361 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
362 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
363 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
364 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
365 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
366 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
367 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
368 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
369 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
370 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
371 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
372 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
373 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
374 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
375 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
376 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
377 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
378 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
379 0xf2, 0x5d, 0x58, 0x07
382 static void test_hashes(void)
384 static const unsigned char md2hash[16] = {
385 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
386 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
387 static const unsigned char md4hash[16] = {
388 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
389 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
390 static const unsigned char empty_md5hash[16] = {
391 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
392 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
393 static const unsigned char md5hash[16] = {
394 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
395 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
396 static const unsigned char sha1hash[20] = {
397 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
398 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
399 static const unsigned char signed_ssl3_shamd5_hash[] = {
400 0x4f,0xcc,0x2f,0x33,0x44,0x60,0x76,0x16,0x13,0xc8,0xff,0xd4,0x59,0x19,
401 0xde,0x85,0x44,0x72,0x47,0x98,0x01,0xfb,0x67,0x5c,0x5b,0x35,0x15,0x0f,
402 0x91,0xda,0xc7,0x7c,0xfb,0xe2,0x18,0xef,0xac,0x31,0x40,0x7b,0xa9,0x83,
403 0xdb,0x30,0xcd,0x94,0x4b,0x8e,0x3b,0x6c,0x7a,0x86,0x59,0xf0,0xd1,0xd2,
404 0x5e,0xce,0xd4,0x1b,0x7f,0xed,0x24,0xee,0x53,0x5c,0x15,0x97,0x21,0x7c,
405 0x5c,0xea,0xab,0xf5,0xd6,0x4b,0xb3,0xbb,0x14,0xf5,0x59,0x9e,0x21,0x90,
406 0x21,0x99,0x19,0xad,0xa2,0xa6,0xea,0x61,0xc1,0x41,0xe2,0x70,0x77,0xf7,
407 0x15,0x68,0x96,0x1e,0x5c,0x84,0x97,0xe3,0x5c,0xd2,0xd9,0xfb,0x87,0x6f,
408 0x11,0x21,0x82,0x43,0x76,0x32,0xa4,0x38,0x7b,0x85,0x22,0x30,0x1e,0x55,
410 unsigned char pbData[2048];
412 HCRYPTHASH hHash, hHashClone;
414 BYTE pbHashValue[36];
415 BYTE pbSigValue[128];
416 HCRYPTKEY hKeyExchangeKey;
417 DWORD hashlen, len, error;
420 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
423 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
425 /* rsaenh compiled without OpenSSL */
426 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
428 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
429 ok(result, "%08x\n", GetLastError());
432 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
433 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
436 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
437 ok(result, "%08x\n", GetLastError());
439 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
441 result = CryptDestroyHash(hHash);
442 ok(result, "%08x\n", GetLastError());
446 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
447 ok(result, "%08x\n", GetLastError());
449 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
450 ok(result, "%08x\n", GetLastError());
453 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
454 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
457 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
458 ok(result, "%08x\n", GetLastError());
460 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
462 result = CryptDestroyHash(hHash);
463 ok(result, "%08x\n", GetLastError());
466 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
467 ok(result, "%08x\n", GetLastError());
470 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
471 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
473 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
474 ok(result, "%08x\n", GetLastError());
477 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
478 ok(result, "%08x\n", GetLastError());
480 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
482 result = CryptDestroyHash(hHash);
483 ok(result, "%08x\n", GetLastError());
485 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
486 ok(result, "%08x\n", GetLastError());
488 /* The hash is available even if CryptHashData hasn't been called */
490 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
491 ok(result, "%08x\n", GetLastError());
493 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
495 /* It's also stable: getting it twice results in the same value */
496 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
497 ok(result, "%08x\n", GetLastError());
499 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
501 /* Can't add data after the hash been retrieved */
502 SetLastError(0xdeadbeef);
503 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
504 ok(!result, "Expected failure\n");
505 ok(GetLastError() == NTE_BAD_HASH_STATE ||
506 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
507 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
509 /* You can still retrieve the hash, its value just hasn't changed */
510 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
511 ok(result, "%08x\n", GetLastError());
513 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
515 result = CryptDestroyHash(hHash);
516 ok(result, "%08x\n", GetLastError());
519 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
520 ok(result, "%08x\n", GetLastError());
522 result = CryptHashData(hHash, pbData, 5, 0);
523 ok(result, "%08x\n", GetLastError());
525 if(pCryptDuplicateHash) {
526 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
527 ok(result, "%08x\n", GetLastError());
529 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
530 ok(result, "%08x\n", GetLastError());
533 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
534 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
537 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
538 ok(result, "%08x\n", GetLastError());
540 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
542 result = CryptDestroyHash(hHashClone);
543 ok(result, "%08x\n", GetLastError());
546 result = CryptDestroyHash(hHash);
547 ok(result, "%08x\n", GetLastError());
549 /* The SHA-2 variants aren't supported in the RSA full provider */
550 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
551 ok(!result && GetLastError() == NTE_BAD_ALGID,
552 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
553 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
554 ok(!result && GetLastError() == NTE_BAD_ALGID,
555 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
556 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
557 ok(!result && GetLastError() == NTE_BAD_ALGID,
558 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
560 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
561 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
563 result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash);
564 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
566 /* release provider before using the hash */
567 result = CryptReleaseContext(prov, 0);
568 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
570 SetLastError(0xdeadbeef);
571 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
572 error = GetLastError();
573 ok(!result, "CryptHashData succeeded\n");
574 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
576 SetLastError(0xdeadbeef);
577 result = CryptDestroyHash(hHash);
578 error = GetLastError();
579 ok(!result, "CryptDestroyHash succeeded\n");
580 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
582 if (!pCryptDuplicateHash)
584 win_skip("CryptDuplicateHash is not available\n");
588 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
589 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
591 result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
592 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
594 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
595 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
597 result = pCryptDuplicateHash(hHash, NULL, 0, &hHashClone);
598 ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
601 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
602 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
604 /* add data after duplicating the hash */
605 result = CryptHashData(hHash, (const BYTE *)"more data", sizeof("more data"), 0);
606 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
608 result = CryptDestroyHash(hHash);
609 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
611 result = CryptDestroyHash(hHashClone);
612 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
614 result = CryptReleaseContext(prov, 0);
615 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
617 /* Test CALG_SSL3_SHAMD5 */
618 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
619 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
621 /* Step 1: create an MD5 hash of the data */
622 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
623 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
624 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
625 ok(result, "%08x\n", GetLastError());
627 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
628 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
629 result = CryptDestroyHash(hHash);
630 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
631 /* Step 2: create a SHA1 hash of the data */
632 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
633 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
634 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
635 ok(result, "%08x\n", GetLastError());
637 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue + 16, &len, 0);
638 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
639 result = CryptDestroyHash(hHash);
640 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
641 /* Step 3: create a CALG_SSL3_SHAMD5 hash handle */
642 result = CryptCreateHash(hProv, CALG_SSL3_SHAMD5, 0, 0, &hHash);
643 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
644 /* Test that CryptHashData fails on this hash */
645 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
646 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
647 result = CryptSetHashParam(hHash, HP_HASHVAL, pbHashValue, 0);
648 ok(result, "%08x\n", GetLastError());
649 len = (DWORD)sizeof(abPlainPrivateKey);
650 result = CryptImportKey(hProv, abPlainPrivateKey, len, 0, 0, &hKeyExchangeKey);
651 ok(result, "%08x\n", GetLastError());
653 result = CryptSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &len);
654 ok(result, "%08x\n", GetLastError());
655 ok(len == 128, "expected len 128, got %d\n", len);
656 result = CryptSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, pbSigValue, &len);
657 ok(result, "%08x\n", GetLastError());
658 ok(!memcmp(pbSigValue, signed_ssl3_shamd5_hash, len), "unexpected value\n");
659 if (len != 128 || memcmp(pbSigValue, signed_ssl3_shamd5_hash, len))
661 printBytes("expected", signed_ssl3_shamd5_hash,
662 sizeof(signed_ssl3_shamd5_hash));
663 printBytes("got", pbSigValue, len);
665 result = CryptDestroyKey(hKeyExchangeKey);
666 ok(result, "CryptDestroyKey failed 0x%08x\n", GetLastError());
667 result = CryptDestroyHash(hHash);
668 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
669 result = CryptReleaseContext(prov, 0);
670 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
673 static void test_block_cipher_modes(void)
675 static const BYTE plain[23] = {
676 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
677 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
678 static const BYTE ecb[24] = {
679 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
680 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
681 static const BYTE cbc[24] = {
682 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
683 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
684 static const BYTE cfb[24] = {
685 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
686 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
692 result = derive_key(CALG_RC2, &hKey, 40);
695 memcpy(abData, plain, sizeof(plain));
697 dwMode = CRYPT_MODE_ECB;
698 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
699 ok(result, "%08x\n", GetLastError());
701 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
702 ok(result, "%08x\n", GetLastError());
703 ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
706 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
707 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
708 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
710 SetLastError(ERROR_SUCCESS);
712 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
713 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
714 "%08x, dwLen: %d\n", GetLastError(), dwLen);
716 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
717 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
718 "%08x, dwLen: %d\n", GetLastError(), dwLen);
720 dwMode = CRYPT_MODE_CBC;
721 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
722 ok(result, "%08x\n", GetLastError());
725 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
726 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
727 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
730 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
731 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
732 "%08x, dwLen: %d\n", GetLastError(), dwLen);
734 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
735 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
736 "%08x, dwLen: %d\n", GetLastError(), dwLen);
738 dwMode = CRYPT_MODE_CFB;
739 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
740 ok(result, "%08x\n", GetLastError());
743 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
744 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
747 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
748 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
749 "%08x, dwLen: %d\n", GetLastError(), dwLen);
752 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
753 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
756 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
757 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
758 "%08x, dwLen: %d\n", GetLastError(), dwLen);
760 dwMode = CRYPT_MODE_OFB;
761 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
762 ok(result, "%08x\n", GetLastError());
765 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
766 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
768 CryptDestroyKey(hKey);
771 static void test_3des112(void)
776 unsigned char pbData[16];
779 result = derive_key(CALG_3DES_112, &hKey, 0);
781 /* rsaenh compiled without OpenSSL */
782 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
786 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
789 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
790 ok(result, "%08x\n", GetLastError());
792 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
793 ok(result, "%08x\n", GetLastError());
797 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
799 dwLen = cTestData[i].enclen;
800 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
801 ok(result, "%08x\n", GetLastError());
802 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
804 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
805 ok(result, "%08x\n", GetLastError());
806 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
807 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
808 if((dwLen != cTestData[i].enclen) ||
809 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
811 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
812 printBytes("got",pbData,dwLen);
815 result = CryptDestroyKey(hKey);
816 ok(result, "%08x\n", GetLastError());
819 static void test_des(void)
824 unsigned char pbData[16];
827 result = derive_key(CALG_DES, &hKey, 56);
829 /* rsaenh compiled without OpenSSL */
830 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
834 dwMode = CRYPT_MODE_ECB;
835 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
836 ok(result, "%08x\n", GetLastError());
838 dwLen = sizeof(DWORD);
839 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
840 ok(result, "%08x\n", GetLastError());
842 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
845 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
846 ok(result, "%08x\n", GetLastError());
848 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
849 ok(result, "%08x\n", GetLastError());
853 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
855 dwLen = cTestData[i].enclen;
856 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
857 ok(result, "%08x\n", GetLastError());
858 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
860 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
861 ok(result, "%08x\n", GetLastError());
862 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
863 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
864 if((dwLen != cTestData[i].enclen) ||
865 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
867 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
868 printBytes("got",pbData,dwLen);
872 result = CryptDestroyKey(hKey);
873 ok(result, "%08x\n", GetLastError());
876 static void test_3des(void)
881 unsigned char pbData[16];
882 static const BYTE des3[16] = {
883 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
884 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
887 result = derive_key(CALG_3DES, &hKey, 0);
890 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
893 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
894 ok(result, "%08x\n", GetLastError());
896 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
898 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
899 ok(result, "%08x\n", GetLastError());
903 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
905 dwLen = cTestData[i].enclen;
906 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
907 ok(result, "%08x\n", GetLastError());
908 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
910 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
911 ok(result, "%08x\n", GetLastError());
912 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
913 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
914 if((dwLen != cTestData[i].enclen) ||
915 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
917 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
918 printBytes("got",pbData,dwLen);
921 result = CryptDestroyKey(hKey);
922 ok(result, "%08x\n", GetLastError());
925 static void test_aes(int keylen)
930 unsigned char pbData[16];
936 result = derive_key(CALG_AES_256, &hKey, 0);
939 result = derive_key(CALG_AES_192, &hKey, 0);
943 result = derive_key(CALG_AES_128, &hKey, 0);
948 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
950 /* AES provider doesn't support salt */
951 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
952 ok((!result && GetLastError() == NTE_BAD_KEY) || result /* Win7 */,
953 "expected NTE_BAD_KEY, got %08x\n", GetLastError());
956 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
957 ok(result, "%08x\n", GetLastError());
959 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
960 ok(result, "%08x\n", GetLastError());
964 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
966 dwLen = cTestData[i].enclen;
967 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
968 ok(result, "%08x\n", GetLastError());
969 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
971 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
972 ok(result, "%08x\n", GetLastError());
973 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
974 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
975 if((dwLen != cTestData[i].enclen) ||
976 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
978 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
979 printBytes("got",pbData,dwLen);
982 result = CryptDestroyKey(hKey);
983 ok(result, "%08x\n", GetLastError());
986 static void test_sha2(void)
988 static const unsigned char sha256hash[32] = {
989 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
990 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
991 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
994 static const unsigned char sha384hash[48] = {
995 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
996 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
997 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
998 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
999 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
1001 static const unsigned char sha512hash[64] = {
1002 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1003 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1004 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1005 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1006 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1007 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1008 0xb7, 0xf4, 0x81, 0xd4
1010 unsigned char pbData[2048];
1013 BYTE pbHashValue[64];
1017 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1020 SetLastError(0xdeadbeef);
1021 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1022 if (!result && GetLastError() == NTE_BAD_ALGID) {
1023 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1026 ok(result, "%08x\n", GetLastError());
1028 len = sizeof(DWORD);
1029 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1030 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1032 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1033 ok(result, "%08x\n", GetLastError());
1036 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1037 ok(result, "%08x\n", GetLastError());
1039 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1041 result = CryptDestroyHash(hHash);
1042 ok(result, "%08x\n", GetLastError());
1046 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1047 ok(result, "%08x\n", GetLastError());
1049 len = sizeof(DWORD);
1050 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1051 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1053 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1054 ok(result, "%08x\n", GetLastError());
1057 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1058 ok(result, "%08x\n", GetLastError());
1060 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1062 result = CryptDestroyHash(hHash);
1063 ok(result, "%08x\n", GetLastError());
1067 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1068 ok(result, "%08x\n", GetLastError());
1070 len = sizeof(DWORD);
1071 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1072 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1074 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1075 ok(result, "%08x\n", GetLastError());
1078 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1079 ok(result, "%08x\n", GetLastError());
1081 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1083 result = CryptDestroyHash(hHash);
1084 ok(result, "%08x\n", GetLastError());
1088 static void test_rc2(void)
1090 static const BYTE rc2_40_encrypted[16] = {
1091 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1092 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1093 static const BYTE rc2_128_encrypted[] = {
1094 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
1099 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
1101 unsigned char pbData[2000], pbHashValue[16];
1104 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1107 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1109 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1111 CRYPT_INTEGER_BLOB salt;
1113 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1114 ok(result, "%08x\n", GetLastError());
1117 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1118 ok(result, "%08x\n", GetLastError());
1120 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1121 ok(result, "%08x\n", GetLastError());
1123 dwLen = sizeof(DWORD);
1124 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1125 ok(result, "%08x\n", GetLastError());
1127 dwMode = CRYPT_MODE_CBC;
1128 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1129 ok(result, "%08x\n", GetLastError());
1131 dwLen = sizeof(DWORD);
1132 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1133 ok(result, "%08x\n", GetLastError());
1135 dwModeBits = 0xdeadbeef;
1136 dwLen = sizeof(DWORD);
1137 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1138 ok(result, "%08x\n", GetLastError());
1140 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1141 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
1142 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1143 " got %08x\n", dwModeBits);
1145 dwLen = sizeof(DWORD);
1146 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1147 ok(result, "%08x\n", GetLastError());
1149 dwLen = sizeof(DWORD);
1150 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1151 ok(result, "%08x\n", GetLastError());
1153 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1154 ok(result, "%08x\n", GetLastError());
1155 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1156 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1157 HeapFree(GetProcessHeap(), 0, pbTemp);
1159 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1160 ok(result, "%08x\n", GetLastError());
1161 /* The default salt length is always 11... */
1162 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1163 /* and the default salt is always empty. */
1164 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1165 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1166 for (i=0; i<dwLen; i++)
1167 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1168 HeapFree(GetProcessHeap(), 0, pbTemp);
1170 dwLen = sizeof(DWORD);
1171 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1173 result = CryptDestroyHash(hHash);
1174 ok(result, "%08x\n", GetLastError());
1177 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1178 ok(result, "%08x\n", GetLastError());
1180 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1182 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1183 ok(result, "%08x\n", GetLastError());
1184 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1185 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1186 HeapFree(GetProcessHeap(), 0, pbTemp);
1188 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1189 ok(result, "%08x\n", GetLastError());
1191 /* Setting the salt also succeeds... */
1192 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1193 ok(result, "setting salt failed: %08x\n", GetLastError());
1194 /* but the resulting salt length is now zero? */
1196 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1197 ok(result, "%08x\n", GetLastError());
1199 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1200 "unexpected salt length %d\n", dwLen);
1201 /* What sizes salt can I set? */
1202 salt.pbData = pbData;
1203 for (i=0; i<24; i++)
1206 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1207 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1208 /* The returned salt length is the same as the set salt length */
1209 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1210 ok(result, "%08x\n", GetLastError());
1211 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1214 SetLastError(0xdeadbeef);
1215 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1217 broken(result), /* Win9x, WinMe, NT4, W2K */
1218 "%08x\n", GetLastError());
1220 result = CryptDestroyKey(hKey);
1221 ok(result, "%08x\n", GetLastError());
1224 /* Again, but test setting the effective key len */
1225 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1227 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1229 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1231 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1232 ok(result, "%08x\n", GetLastError());
1235 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1236 ok(result, "%08x\n", GetLastError());
1238 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1239 ok(result, "%08x\n", GetLastError());
1241 SetLastError(0xdeadbeef);
1242 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1243 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1245 SetLastError(0xdeadbeef);
1246 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1247 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1249 SetLastError(0xdeadbeef);
1250 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1252 dwLen = sizeof(dwKeyLen);
1253 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1254 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1255 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1256 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1259 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1260 ok(result, "%d\n", GetLastError());
1262 dwLen = sizeof(dwKeyLen);
1263 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1264 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1265 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1266 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1268 result = CryptDestroyHash(hHash);
1269 ok(result, "%08x\n", GetLastError());
1272 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1273 ok(result, "%08x\n", GetLastError());
1275 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1276 "RC2 encryption failed!\n");
1278 /* Oddly enough this succeeds, though it should have no effect */
1280 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1281 ok(result, "%d\n", GetLastError());
1283 result = CryptDestroyKey(hKey);
1284 ok(result, "%08x\n", GetLastError());
1288 static void test_rc4(void)
1290 static const BYTE rc4[16] = {
1291 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1292 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1296 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1297 unsigned char pbData[2000], *pbTemp;
1298 unsigned char pszBuffer[256];
1301 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1304 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1306 /* rsaenh compiled without OpenSSL */
1307 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1309 CRYPT_INTEGER_BLOB salt;
1311 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1312 ok(result, "%08x\n", GetLastError());
1315 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1316 ok(result, "%08x\n", GetLastError());
1318 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1319 ok(result, "%08x\n", GetLastError());
1321 dwLen = sizeof(DWORD);
1322 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1323 ok(result, "%08x\n", GetLastError());
1325 dwLen = sizeof(DWORD);
1326 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1327 ok(result, "%08x\n", GetLastError());
1329 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1330 ok(result, "%08x\n", GetLastError());
1331 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1332 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1333 HeapFree(GetProcessHeap(), 0, pbTemp);
1335 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1336 ok(result, "%08x\n", GetLastError());
1337 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1338 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1339 HeapFree(GetProcessHeap(), 0, pbTemp);
1341 dwLen = sizeof(DWORD);
1342 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1344 result = CryptDestroyHash(hHash);
1345 ok(result, "%08x\n", GetLastError());
1348 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1349 ok(result, "%08x\n", GetLastError());
1351 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1352 ok(result, "%08x\n", GetLastError());
1354 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1356 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1357 ok(result, "%08x\n", GetLastError());
1359 /* Setting the salt also succeeds... */
1360 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1361 ok(result, "setting salt failed: %08x\n", GetLastError());
1362 /* but the resulting salt length is now zero? */
1364 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1365 ok(result, "%08x\n", GetLastError());
1367 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1368 "unexpected salt length %d\n", dwLen);
1369 /* What sizes salt can I set? */
1370 salt.pbData = pbData;
1371 for (i=0; i<24; i++)
1374 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1375 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1376 /* The returned salt length is the same as the set salt length */
1377 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1378 ok(result, "%08x\n", GetLastError());
1379 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1382 SetLastError(0xdeadbeef);
1383 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1385 broken(result), /* Win9x, WinMe, NT4, W2K */
1386 "%08x\n", GetLastError());
1388 result = CryptDestroyKey(hKey);
1389 ok(result, "%08x\n", GetLastError());
1393 static void test_hmac(void) {
1397 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1398 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1401 static const BYTE hmac[16] = {
1402 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1403 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1406 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1408 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1410 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1411 ok(result, "%08x\n", GetLastError());
1412 if (!result) return;
1414 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1415 ok(result, "%08x\n", GetLastError());
1417 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1418 ok(result, "%08x\n", GetLastError());
1420 dwLen = sizeof(abData)/sizeof(BYTE);
1421 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1422 ok(result, "%08x\n", GetLastError());
1424 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1426 result = CryptDestroyHash(hHash);
1427 ok(result, "%08x\n", GetLastError());
1429 result = CryptDestroyKey(hKey);
1430 ok(result, "%08x\n", GetLastError());
1432 /* Provoke errors */
1433 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1434 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1437 static void test_mac(void) {
1442 BYTE abData[256], abEnc[264];
1443 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1446 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1447 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1449 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1452 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1453 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1455 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1456 ok(result, "%08x\n", GetLastError());
1457 if (!result) return;
1459 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1460 ok(result, "%08x\n", GetLastError());
1462 dwLen = sizeof(abData)/sizeof(BYTE);
1463 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1464 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1466 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1468 result = CryptDestroyHash(hHash);
1469 ok(result, "%08x\n", GetLastError());
1471 result = CryptDestroyKey(hKey);
1472 ok(result, "%08x\n", GetLastError());
1474 /* Provoke errors */
1475 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1477 SetLastError(0xdeadbeef);
1478 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1479 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1480 broken(result), /* Win9x, WinMe, NT4, W2K */
1481 "%08x\n", GetLastError());
1483 result = CryptDestroyKey(hKey);
1484 ok(result, "%08x\n", GetLastError());
1487 static void test_import_private(void)
1490 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1492 static BYTE abSessionKey[148] = {
1493 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1494 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1495 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1496 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1497 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1498 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1499 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1500 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1501 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1502 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1503 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1504 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1505 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1506 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1507 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1508 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1509 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1510 0x04, 0x8c, 0x49, 0x92
1512 static BYTE abEncryptedMessage[12] = {
1513 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1514 0x1c, 0xfd, 0xde, 0x71
1517 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1518 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1520 /* rsaenh compiled without OpenSSL */
1521 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1525 dwLen = (DWORD)sizeof(abSessionKey);
1526 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1527 ok(result, "%08x\n", GetLastError());
1528 if (!result) return;
1531 dwLen = sizeof(DWORD);
1532 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1533 ok(result, "%08x\n", GetLastError());
1535 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1536 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1537 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1538 " got %08x\n", dwVal);
1540 dwLen = (DWORD)sizeof(abEncryptedMessage);
1541 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1542 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1543 "%08x, len: %d\n", GetLastError(), dwLen);
1544 CryptDestroyKey(hSessionKey);
1546 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1548 dwLen = (DWORD)sizeof(abSessionKey);
1549 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1550 ok(result, "%08x\n", GetLastError());
1551 CryptDestroyKey(hSessionKey);
1552 if (!result) return;
1554 dwLen = (DWORD)sizeof(abSessionKey);
1555 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1556 ok(result, "%08x\n", GetLastError());
1557 if (!result) return;
1559 CryptDestroyKey(hSessionKey);
1560 CryptDestroyKey(hKeyExchangeKey);
1563 static void test_verify_signature(void) {
1565 HCRYPTKEY hPubSignKey;
1566 BYTE abData[] = "Wine rocks!";
1568 BYTE abPubKey[148] = {
1569 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1570 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1571 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1572 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1573 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1574 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1575 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1576 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1577 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1578 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1579 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1580 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1581 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1582 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1583 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1584 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1585 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1586 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1587 0xe1, 0x21, 0x50, 0xac
1589 /* md2 with hash oid */
1590 BYTE abSignatureMD2[128] = {
1591 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1592 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1593 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1594 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1595 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1596 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1597 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1598 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1599 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1600 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1601 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1602 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1603 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1604 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1605 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1606 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1608 /* md2 without hash oid */
1609 BYTE abSignatureMD2NoOID[128] = {
1610 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1611 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1612 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1613 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1614 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1615 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1616 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1617 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1618 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1619 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1620 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1621 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1622 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1623 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1624 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1625 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1627 /* md4 with hash oid */
1628 BYTE abSignatureMD4[128] = {
1629 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1630 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1631 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1632 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1633 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1634 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1635 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1636 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1637 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1638 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1639 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1640 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1641 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1642 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1643 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1644 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1646 /* md4 without hash oid */
1647 BYTE abSignatureMD4NoOID[128] = {
1648 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1649 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1650 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1651 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1652 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1653 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1654 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1655 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1656 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1657 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1658 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1659 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1660 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1661 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1662 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1663 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1665 /* md5 with hash oid */
1666 BYTE abSignatureMD5[128] = {
1667 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1668 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1669 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1670 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1671 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1672 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1673 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1674 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1675 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1676 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1677 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1678 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1679 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1680 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1681 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1682 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1684 /* md5 without hash oid */
1685 BYTE abSignatureMD5NoOID[128] = {
1686 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1687 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1688 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1689 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1690 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1691 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1692 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1693 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1694 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1695 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1696 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1697 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1698 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1699 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1700 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1701 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1703 /* sha with hash oid */
1704 BYTE abSignatureSHA[128] = {
1705 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1706 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1707 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1708 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1709 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1710 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1711 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1712 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1713 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1714 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1715 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1716 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1717 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1718 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1719 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1720 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1722 /* sha without hash oid */
1723 BYTE abSignatureSHANoOID[128] = {
1724 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1725 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1726 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1727 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1728 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1729 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1730 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1731 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1732 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1733 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1734 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1735 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1736 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1737 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1738 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1739 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1742 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1743 ok(result, "%08x\n", GetLastError());
1744 if (!result) return;
1746 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1747 ok(result, "%08x\n", GetLastError());
1748 if (!result) return;
1750 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1751 ok(result, "%08x\n", GetLastError());
1752 if (!result) return;
1754 /*check that a NULL pointer signature is correctly handled*/
1755 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1756 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1757 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1760 /* check that we get a bad signature error when the signature is too short*/
1761 SetLastError(0xdeadbeef);
1762 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1763 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1764 broken(result), /* Win9x, WinMe, NT4 */
1765 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1767 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1768 ok(result, "%08x\n", GetLastError());
1769 if (!result) return;
1771 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1772 ok(result, "%08x\n", GetLastError());
1773 if (!result) return;
1775 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1776 * the OID at all. */
1777 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1778 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1779 if (result) return;*/
1781 CryptDestroyHash(hHash);
1783 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1784 ok(result, "%08x\n", GetLastError());
1785 if (!result) return;
1787 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1788 ok(result, "%08x\n", GetLastError());
1789 if (!result) return;
1791 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1792 ok(result, "%08x\n", GetLastError());
1793 if (!result) return;
1795 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1796 ok(result, "%08x\n", GetLastError());
1797 if (!result) return;
1799 CryptDestroyHash(hHash);
1801 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1802 ok(result, "%08x\n", GetLastError());
1803 if (!result) return;
1805 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1806 ok(result, "%08x\n", GetLastError());
1807 if (!result) return;
1809 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1810 ok(result, "%08x\n", GetLastError());
1811 if (!result) return;
1813 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1814 ok(result, "%08x\n", GetLastError());
1815 if (!result) return;
1817 CryptDestroyHash(hHash);
1819 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1820 ok(result, "%08x\n", GetLastError());
1821 if (!result) return;
1823 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1824 ok(result, "%08x\n", GetLastError());
1825 if (!result) return;
1827 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1828 ok(result, "%08x\n", GetLastError());
1829 if (!result) return;
1831 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1832 ok(result, "%08x\n", GetLastError());
1833 if (!result) return;
1835 CryptDestroyHash(hHash);
1836 CryptDestroyKey(hPubSignKey);
1839 static void test_rsa_encrypt(void)
1842 BYTE abData[2048] = "Wine rocks!";
1846 /* It is allowed to use the key exchange key for encryption/decryption */
1847 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1848 ok (result, "%08x\n", GetLastError());
1849 if (!result) return;
1852 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1853 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1854 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1856 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1857 ok (result, "%08x\n", GetLastError());
1858 if (!result) return;
1860 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1861 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1864 dwLen = sizeof(DWORD);
1865 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1866 ok(result, "%08x\n", GetLastError());
1868 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1869 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1870 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1871 " got %08x\n", dwVal);
1873 /* An RSA key doesn't support salt */
1874 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1875 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
1876 "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
1878 /* The key exchange key's public key may be exported.. */
1879 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1880 ok(result, "%08x\n", GetLastError());
1881 /* but its private key may not be. */
1882 SetLastError(0xdeadbeef);
1883 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1884 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1885 broken(result), /* Win9x/NT4 */
1886 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1887 /* Setting the permissions of the key exchange key isn't allowed, either. */
1888 dwVal |= CRYPT_EXPORT;
1889 SetLastError(0xdeadbeef);
1890 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1892 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1893 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1895 CryptDestroyKey(hRSAKey);
1897 /* It is not allowed to use the signature key for encryption/decryption */
1898 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1899 ok (result, "%08x\n", GetLastError());
1900 if (!result) return;
1903 dwLen = sizeof(DWORD);
1904 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1905 ok(result, "%08x\n", GetLastError());
1907 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1908 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1909 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1910 " got %08x\n", dwVal);
1912 /* The signature key's public key may also be exported.. */
1913 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1914 ok(result, "%08x\n", GetLastError());
1915 /* but its private key may not be. */
1916 SetLastError(0xdeadbeef);
1917 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1918 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1919 broken(result), /* Win9x/NT4 */
1920 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1921 /* Setting the permissions of the signature key isn't allowed, either. */
1922 dwVal |= CRYPT_EXPORT;
1923 SetLastError(0xdeadbeef);
1924 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1926 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1927 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1930 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1931 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1933 CryptDestroyKey(hRSAKey);
1936 static void test_import_export(void)
1938 DWORD dwLen, dwDataLen, dwVal;
1939 HCRYPTKEY hPublicKey, hPrivKey;
1942 BYTE emptyKey[2048], *exported_key;
1943 static BYTE abPlainPublicKey[84] = {
1944 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1945 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1946 0x01, 0x00, 0x01, 0x00, 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, 0x11, 0x11, 0x11, 0x11,
1953 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1954 0x11, 0x11, 0x11, 0x11
1956 static BYTE priv_key_with_high_bit[] = {
1957 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1958 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1959 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1960 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1961 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1962 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1963 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1964 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1965 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1966 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1967 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1968 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1969 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1970 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1971 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1972 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1973 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1974 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1975 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1976 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1977 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1978 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1979 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1980 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1981 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1982 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1983 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1984 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1985 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1986 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1987 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1988 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1989 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1990 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1991 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1992 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1993 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1994 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1995 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1996 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1997 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1998 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1999 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2000 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2001 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2002 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2003 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2004 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2005 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2006 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2007 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2008 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2009 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2010 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2011 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2012 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2013 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2014 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2015 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2016 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2017 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2018 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2019 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2020 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2021 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2022 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2023 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2024 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2025 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2026 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2027 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2028 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2029 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2030 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2031 0xb6, 0x5f, 0x01, 0x5e
2033 static const BYTE expected_exported_priv_key[] = {
2034 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2035 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2036 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2037 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2038 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2039 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2040 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2041 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2042 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2043 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2044 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2045 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2046 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2047 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2048 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2049 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2050 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2051 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2052 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2053 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2054 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2055 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2056 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2057 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2058 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2059 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2060 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2061 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2062 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2063 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2064 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2065 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2066 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2067 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2068 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2069 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2070 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2071 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2072 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2073 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2074 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2075 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2076 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2077 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2078 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2079 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2080 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2081 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2082 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2083 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2084 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2085 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2086 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2087 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2088 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2089 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2090 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2091 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2092 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2093 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2094 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2095 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2096 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2097 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2098 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2099 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2100 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2101 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2102 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2103 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2104 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2105 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2106 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2107 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2108 0xb6, 0x5f, 0x01, 0x5e
2112 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2113 ok(result, "failed to import the public key\n");
2115 dwDataLen=sizeof(algID);
2116 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2117 ok(result, "failed to get the KP_ALGID from the imported public key\n");
2118 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2121 dwDataLen = sizeof(DWORD);
2122 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2123 ok(result, "%08x\n", GetLastError());
2125 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2126 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2127 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2128 " got %08x\n", dwVal);
2129 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2130 ok(result, "failed to export the fresh imported public key\n");
2131 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2132 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2134 CryptDestroyKey(hPublicKey);
2136 result = CryptImportKey(hProv, priv_key_with_high_bit,
2137 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2138 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2140 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2141 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2142 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2143 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2145 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2147 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2149 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2150 "unexpected value\n");
2152 HeapFree(GetProcessHeap(), 0, exported_key);
2154 CryptDestroyKey(hPrivKey);
2157 static void test_import_hmac(void)
2159 /* Test cases from RFC 2202, section 3 */
2160 static const struct rfc2202_test_case {
2164 const DWORD data_len;
2167 { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2168 "\x0b\x0b\x0b\x0b", 20,
2170 "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2171 "\xf1\x46\xbe\x00" },
2173 "what do ya want for nothing?", 28,
2174 "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2175 "\x25\x9a\x7c\x79" },
2176 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2177 "\xaa\xaa\xaa\xaa", 20,
2178 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2179 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2180 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2182 "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2183 "\x63\xf1\x75\xd3" },
2184 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2185 "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2186 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2187 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2188 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2190 "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2191 "\x2d\x72\x35\xda" },
2192 { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2193 "\x0c\x0c\x0c\x0c", 20,
2194 "Test With Truncation", 20,
2195 "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2196 "\x4a\x9a\x5a\x04" },
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"
2200 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2201 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2203 "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2204 "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2205 "\xed\x40\x21\x12" },
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"
2209 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2210 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2212 "Test Using Larger Than Block-Size Key and Larger "
2213 "Than One Block-Size Data", 73,
2214 "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2215 "\xbb\xff\x1a\x91" }
2219 for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++)
2221 const struct rfc2202_test_case *test_case = &cases[i];
2222 DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2223 BYTE *blob = HeapAlloc(GetProcessHeap(), 0, size);
2227 BLOBHEADER *header = (BLOBHEADER *)blob;
2228 DWORD *key_len = (DWORD *)(header + 1);
2229 BYTE *key_bytes = (BYTE *)(key_len + 1);
2233 header->bType = PLAINTEXTKEYBLOB;
2234 header->bVersion = CUR_BLOB_VERSION;
2235 header->reserved = 0;
2236 header->aiKeyAlg = CALG_RC2;
2237 *key_len = test_case->key_len;
2238 memcpy(key_bytes, test_case->key, *key_len);
2239 result = CryptImportKey(hProv, blob, size, 0, CRYPT_IPSEC_HMAC_KEY, &key);
2240 ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
2244 HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2248 result = CryptCreateHash(hProv, CALG_HMAC, key, 0, &hash);
2249 ok(result, "CryptCreateHash failed on test case %d: %08x\n", i, GetLastError());
2250 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2251 ok(result, "CryptSetHashParam failed on test case %d: %08x\n", i, GetLastError());
2252 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2253 ok(result, "CryptHashData failed on test case %d: %08x\n", i, GetLastError());
2254 digest_size = sizeof(digest);
2255 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2256 ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
2257 ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected value on test case %d\n", i);
2258 CryptDestroyHash(hash);
2259 CryptDestroyKey(key);
2261 HeapFree(GetProcessHeap(), 0, blob);
2266 static void test_schannel_provider(void)
2269 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2270 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2273 SCHANNEL_ALG saSChannelAlg;
2274 CRYPT_DATA_BLOB data_blob;
2275 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2276 BYTE abTLS1Master[140] = {
2277 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2278 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2279 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2280 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2281 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2282 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2283 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2284 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2285 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2286 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2287 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2288 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2289 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2290 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2291 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2292 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2293 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2294 0xd3, 0x1e, 0x82, 0xb3
2296 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2297 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2298 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2299 BYTE abClientFinished[16] = "client finished";
2300 BYTE abData[16] = "Wine rocks!";
2302 static const BYTE abEncryptedData[16] = {
2303 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2304 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2306 static const BYTE abPRF[16] = {
2307 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2308 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2310 static const BYTE abMD5[16] = {
2311 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2312 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2315 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2318 win_skip("no PROV_RSA_SCHANNEL support\n");
2321 ok (result, "%08x\n", GetLastError());
2323 CryptReleaseContext(hProv, 0);
2325 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2326 ok (result, "%08x\n", GetLastError());
2327 if (!result) return;
2329 /* To get deterministic results, we import the TLS1 master secret (which
2330 * is typically generated from a random generator). Therefore, we need
2332 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2333 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2334 ok (result, "%08x\n", GetLastError());
2335 if (!result) return;
2337 dwLen = (DWORD)sizeof(abTLS1Master);
2338 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2339 ok (result, "%08x\n", GetLastError());
2340 if (!result) return;
2342 /* Setting the TLS1 client and server random parameters, as well as the
2343 * MAC and encryption algorithm parameters. */
2344 data_blob.cbData = 33;
2345 data_blob.pbData = abClientSecret;
2346 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2347 ok (result, "%08x\n", GetLastError());
2348 if (!result) return;
2350 data_blob.cbData = 33;
2351 data_blob.pbData = abServerSecret;
2352 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2353 ok (result, "%08x\n", GetLastError());
2354 if (!result) return;
2356 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2357 saSChannelAlg.Algid = CALG_DES;
2358 saSChannelAlg.cBits = 64;
2359 saSChannelAlg.dwFlags = 0;
2360 saSChannelAlg.dwReserved = 0;
2361 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2362 ok (result, "%08x\n", GetLastError());
2363 if (!result) return;
2365 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2366 saSChannelAlg.Algid = CALG_MD5;
2367 saSChannelAlg.cBits = 128;
2368 saSChannelAlg.dwFlags = 0;
2369 saSChannelAlg.dwReserved = 0;
2370 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2371 ok (result, "%08x\n", GetLastError());
2372 if (!result) return;
2374 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2375 * (Keys can only be derived from hashes, not from other keys.) */
2376 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2377 ok (result, "%08x\n", GetLastError());
2378 if (!result) return;
2380 /* Deriving the server write encryption key from the master hash */
2381 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2382 ok (result, "%08x\n", GetLastError());
2383 if (!result) return;
2385 /* Encrypting some data with the server write encryption key and checking the result. */
2387 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2388 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2390 /* Second test case: Test the TLS1 pseudo random number function. */
2391 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2392 ok (result, "%08x\n", GetLastError());
2393 if (!result) return;
2395 /* Set the label and seed parameters for the random number function */
2396 data_blob.cbData = 36;
2397 data_blob.pbData = abHashedHandshakes;
2398 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2399 ok (result, "%08x\n", GetLastError());
2400 if (!result) return;
2402 data_blob.cbData = 15;
2403 data_blob.pbData = abClientFinished;
2404 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2405 ok (result, "%08x\n", GetLastError());
2406 if (!result) return;
2408 /* Generate some pseudo random bytes and check if they are correct. */
2409 dwLen = (DWORD)sizeof(abData);
2410 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2411 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2412 "%08x\n", GetLastError());
2414 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2415 * Hash some data with the HMAC. Compare results. */
2416 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2417 ok (result, "%08x\n", GetLastError());
2418 if (!result) return;
2420 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2421 ok (result, "%08x\n", GetLastError());
2422 if (!result) return;
2424 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2425 ok (result, "%08x\n", GetLastError());
2426 if (!result) return;
2428 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2429 ok (result, "%08x\n", GetLastError());
2430 if (!result) return;
2432 dwLen = (DWORD)sizeof(abMD5Hash);
2433 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2434 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2436 CryptDestroyHash(hHMAC);
2437 CryptDestroyHash(hTLS1PRF);
2438 CryptDestroyHash(hMasterHash);
2439 CryptDestroyKey(hServerWriteMACKey);
2440 CryptDestroyKey(hServerWriteKey);
2441 CryptDestroyKey(hRSAKey);
2442 CryptDestroyKey(hMasterSecret);
2443 CryptReleaseContext(hProv, 0);
2444 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2447 /* Test that a key can be used to encrypt data and exported, and that, when
2448 * the exported key is imported again, can be used to decrypt the original
2451 static void test_rsa_round_trip(void)
2453 static const char test_string[] = "Well this is a fine how-do-you-do.";
2455 HCRYPTKEY signKey, keyExchangeKey;
2457 BYTE data[256], *exportedKey;
2458 DWORD dataLen, keyLen;
2460 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2461 CRYPT_DELETEKEYSET);
2463 /* Generate a new key... */
2464 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2466 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2467 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2468 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2469 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2470 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2471 /* encrypt some data with it... */
2472 memcpy(data, test_string, strlen(test_string) + 1);
2473 dataLen = strlen(test_string) + 1;
2474 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2476 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2477 broken(GetLastError() == NTE_PERM /* NT4 */),
2478 "CryptEncrypt failed: %08x\n", GetLastError());
2479 /* export the key... */
2480 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2482 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2483 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2484 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2486 /* destroy the key... */
2487 CryptDestroyKey(keyExchangeKey);
2488 CryptDestroyKey(signKey);
2489 /* import the key again... */
2490 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2491 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2492 HeapFree(GetProcessHeap(), 0, exportedKey);
2493 /* and decrypt the data encrypted with the original key with the imported
2496 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2497 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2498 broken(GetLastError() == NTE_PERM /* NT4 */),
2499 "CryptDecrypt failed: %08x\n", GetLastError());
2502 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2503 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2505 CryptDestroyKey(keyExchangeKey);
2506 CryptReleaseContext(prov, 0);
2508 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2509 CRYPT_DELETEKEYSET);
2512 static void test_enum_container(void)
2514 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2516 BOOL result, fFound = FALSE;
2518 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2519 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2520 SetLastError(0xdeadbeef);
2521 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2522 ok (result, "%08x\n", GetLastError());
2523 ok (dwBufferLen == MAX_PATH + 1 ||
2524 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2525 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2527 /* If the result fits into abContainerName dwBufferLen is left untouched */
2528 dwBufferLen = (DWORD)sizeof(abContainerName);
2529 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2530 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2532 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2534 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2535 dwBufferLen = (DWORD)sizeof(abContainerName);
2536 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2538 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2541 static BYTE signBlob[] = {
2542 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2543 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2544 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2545 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2546 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2547 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2548 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2549 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2550 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2551 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2552 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2553 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2554 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2555 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2556 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2557 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2558 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2559 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2560 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2561 0xb6,0x85,0x86,0x07 };
2563 static void test_null_provider(void)
2568 DWORD keySpec, dataLen,dwParam;
2569 char szName[MAX_PATH];
2571 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2572 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2573 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2574 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2575 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2576 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2577 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2578 CRYPT_DELETEKEYSET);
2579 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2580 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2581 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2582 CRYPT_DELETEKEYSET);
2583 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2584 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2585 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2586 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2587 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2589 /* Delete the default container. */
2590 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2591 /* Once you've deleted the default container you can't open it as if it
2594 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2595 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2596 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2597 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2598 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2599 CRYPT_VERIFYCONTEXT);
2600 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2601 if (!result) return;
2602 dataLen = sizeof(keySpec);
2603 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2605 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2606 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2607 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2608 * supported, you can't get the keys from this container.
2610 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2611 ok(!result && GetLastError() == NTE_NO_KEY,
2612 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2613 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2614 ok(!result && GetLastError() == NTE_NO_KEY,
2615 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2616 result = CryptReleaseContext(prov, 0);
2617 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2618 /* You can create a new default container. */
2619 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2621 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2622 /* But you still can't get the keys (until one's been generated.) */
2623 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2624 ok(!result && GetLastError() == NTE_NO_KEY,
2625 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2626 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2627 ok(!result && GetLastError() == NTE_NO_KEY,
2628 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2629 CryptReleaseContext(prov, 0);
2630 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2632 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2633 CRYPT_DELETEKEYSET);
2634 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2635 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2636 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2637 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2638 CRYPT_VERIFYCONTEXT);
2639 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2640 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2641 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2643 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2644 if (!result) return;
2645 /* Test provider parameters getter */
2646 dataLen = sizeof(dwParam);
2647 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2648 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2649 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2650 dataLen = sizeof(dwParam);
2651 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2652 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2653 "Expected 0, got 0x%08X\n",dwParam);
2654 dataLen = sizeof(dwParam);
2655 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2656 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2657 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2658 dataLen = sizeof(keySpec);
2659 SetLastError(0xdeadbeef);
2660 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2661 if (!result && GetLastError() == NTE_BAD_TYPE)
2662 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2664 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2665 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2666 /* PP_CONTAINER parameter */
2667 dataLen = sizeof(szName);
2668 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2669 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2670 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2671 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2672 /* PP_UNIQUE_CONTAINER parameter */
2673 dataLen = sizeof(szName);
2674 SetLastError(0xdeadbeef);
2675 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2676 if (!result && GetLastError() == NTE_BAD_TYPE)
2678 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2682 char container[MAX_PATH];
2684 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2685 uniquecontainer(container);
2688 ok(dataLen == strlen(container)+1 ||
2689 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2690 "Expected a param length of 70, got %d\n", dataLen);
2691 ok(!strcmp(container, szName) ||
2692 broken(!strcmp(szName, szContainer)) /* WinME */,
2693 "Wrong container name : %s\n", szName);
2696 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2697 ok(!result && GetLastError() == NTE_NO_KEY,
2698 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2699 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2700 ok(!result && GetLastError() == NTE_NO_KEY,
2701 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2703 /* Importing a key exchange blob.. */
2704 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2706 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2707 CryptDestroyKey(key);
2708 /* allows access to the key exchange key.. */
2709 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2710 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2711 CryptDestroyKey(key);
2712 /* but not to the private key. */
2713 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2714 ok(!result && GetLastError() == NTE_NO_KEY,
2715 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2716 CryptReleaseContext(prov, 0);
2717 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2718 CRYPT_DELETEKEYSET);
2720 /* Whereas importing a sign blob.. */
2721 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2723 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2724 if (!result) return;
2725 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2726 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2727 CryptDestroyKey(key);
2728 /* doesn't allow access to the key exchange key.. */
2729 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2730 ok(!result && GetLastError() == NTE_NO_KEY,
2731 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2732 /* but does to the private key. */
2733 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2734 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2735 CryptDestroyKey(key);
2736 CryptReleaseContext(prov, 0);
2738 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2739 CRYPT_DELETEKEYSET);
2741 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2742 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2744 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2745 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2746 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2747 CryptDestroyKey(key);
2748 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2749 ok(!result, "expected CryptGetUserKey to fail\n");
2750 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2751 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2752 CryptDestroyKey(key);
2753 CryptReleaseContext(prov, 0);
2755 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2756 CRYPT_DELETEKEYSET);
2758 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2759 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2761 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2762 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2763 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2764 CryptDestroyKey(key);
2765 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2766 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2767 CryptDestroyKey(key);
2768 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2769 ok(!result, "expected CryptGetUserKey to fail\n");
2770 CryptReleaseContext(prov, 0);
2772 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2773 CRYPT_DELETEKEYSET);
2775 /* test for the bug in accessing the user key in a container
2777 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2779 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2780 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2781 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2782 CryptDestroyKey(key);
2783 CryptReleaseContext(prov,0);
2784 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2785 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2786 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2787 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2788 CryptDestroyKey(key);
2789 CryptReleaseContext(prov, 0);
2791 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2792 CRYPT_DELETEKEYSET);
2794 /* test the machine key set */
2795 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2796 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2797 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2798 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2799 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2800 CryptReleaseContext(prov, 0);
2801 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2802 CRYPT_MACHINE_KEYSET);
2803 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2804 CryptReleaseContext(prov,0);
2805 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2806 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2807 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2809 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2810 CRYPT_MACHINE_KEYSET);
2811 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2812 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2816 static void test_key_permissions(void)
2818 HCRYPTKEY hKey1, hKey2;
2822 /* Create keys that are exportable */
2823 if (!init_base_environment(CRYPT_EXPORTABLE))
2826 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2827 ok (result, "%08x\n", GetLastError());
2828 if (!result) return;
2831 dwLen = sizeof(DWORD);
2832 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2833 ok(result, "%08x\n", GetLastError());
2835 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2836 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2837 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2838 " got %08x\n", dwVal);
2840 /* The key exchange key's public key may be exported.. */
2841 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2842 ok(result, "%08x\n", GetLastError());
2843 /* and its private key may be too. */
2844 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2845 ok(result, "%08x\n", GetLastError());
2846 /* Turning off the key's export permissions is "allowed".. */
2847 dwVal &= ~CRYPT_EXPORT;
2848 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2850 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2851 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2852 "%08x\n", GetLastError());
2853 /* but it has no effect. */
2855 dwLen = sizeof(DWORD);
2856 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2857 ok(result, "%08x\n", GetLastError());
2859 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2860 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2861 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2862 " got %08x\n", dwVal);
2863 /* Thus, changing the export flag of the key doesn't affect whether the key
2866 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2867 ok(result, "%08x\n", GetLastError());
2869 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2870 ok (result, "%08x\n", GetLastError());
2872 /* A subsequent get of the same key, into a different handle, also doesn't
2873 * show that the permissions have been changed.
2876 dwLen = sizeof(DWORD);
2877 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2878 ok(result, "%08x\n", GetLastError());
2880 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2881 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2882 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2883 " got %08x\n", dwVal);
2885 CryptDestroyKey(hKey2);
2886 CryptDestroyKey(hKey1);
2888 clean_up_base_environment();
2891 static void test_key_initialization(void)
2894 HCRYPTPROV prov1, prov2;
2895 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2897 static BYTE abSessionKey[148] = {
2898 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2899 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2900 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2901 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2902 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2903 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2904 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2905 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2906 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2907 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2908 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2909 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2910 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2911 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2912 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2913 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2914 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2915 0x04, 0x8c, 0x49, 0x92
2918 /* Like init_base_environment, but doesn't generate new keys, as they'll
2919 * be imported instead.
2921 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2923 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2925 ok(result, "%08x\n", GetLastError());
2927 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2928 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2930 dwLen = (DWORD)sizeof(abSessionKey);
2931 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2932 ok(result, "%08x\n", GetLastError());
2934 /* Once the key has been imported, subsequently acquiring a context with
2935 * the same name will allow retrieving the key.
2937 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2938 ok(result, "%08x\n", GetLastError());
2939 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2940 ok(result, "%08x\n", GetLastError());
2941 if (result) CryptDestroyKey(hKey);
2942 CryptReleaseContext(prov2, 0);
2944 CryptDestroyKey(hSessionKey);
2945 CryptDestroyKey(hKeyExchangeKey);
2946 CryptReleaseContext(prov1, 0);
2947 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2948 CRYPT_DELETEKEYSET);
2953 if (!init_base_environment(0))
2965 test_block_cipher_modes();
2966 test_import_private();
2967 test_verify_signature();
2969 test_import_export();
2971 test_enum_container();
2972 clean_up_base_environment();
2973 test_key_permissions();
2974 test_key_initialization();
2975 test_schannel_provider();
2976 test_null_provider();
2977 test_rsa_round_trip();
2978 if (!init_aes_environment())
2984 clean_up_aes_environment();