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 /* Does AES provider 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());
955 ok(!dwLen, "unexpected salt length %d\n", dwLen);
958 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
959 ok(result, "%08x\n", GetLastError());
961 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
962 ok(result, "%08x\n", GetLastError());
966 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
968 dwLen = cTestData[i].enclen;
969 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
970 ok(result, "%08x\n", GetLastError());
971 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
973 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
974 ok(result, "%08x\n", GetLastError());
975 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
976 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
977 if((dwLen != cTestData[i].enclen) ||
978 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
980 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
981 printBytes("got",pbData,dwLen);
984 result = CryptDestroyKey(hKey);
985 ok(result, "%08x\n", GetLastError());
988 static void test_sha2(void)
990 static const unsigned char sha256hash[32] = {
991 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
992 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
993 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
996 static const unsigned char sha384hash[48] = {
997 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
998 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
999 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
1000 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
1001 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
1003 static const unsigned char sha512hash[64] = {
1004 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1005 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1006 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1007 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1008 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1009 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1010 0xb7, 0xf4, 0x81, 0xd4
1012 unsigned char pbData[2048];
1015 BYTE pbHashValue[64];
1019 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1022 SetLastError(0xdeadbeef);
1023 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1024 if (!result && GetLastError() == NTE_BAD_ALGID) {
1025 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1028 ok(result, "%08x\n", GetLastError());
1030 len = sizeof(DWORD);
1031 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1032 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1034 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1035 ok(result, "%08x\n", GetLastError());
1038 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1039 ok(result, "%08x\n", GetLastError());
1041 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1043 result = CryptDestroyHash(hHash);
1044 ok(result, "%08x\n", GetLastError());
1048 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1049 ok(result, "%08x\n", GetLastError());
1051 len = sizeof(DWORD);
1052 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1053 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1055 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1056 ok(result, "%08x\n", GetLastError());
1059 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1060 ok(result, "%08x\n", GetLastError());
1062 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1064 result = CryptDestroyHash(hHash);
1065 ok(result, "%08x\n", GetLastError());
1069 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1070 ok(result, "%08x\n", GetLastError());
1072 len = sizeof(DWORD);
1073 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1074 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1076 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1077 ok(result, "%08x\n", GetLastError());
1080 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1081 ok(result, "%08x\n", GetLastError());
1083 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1085 result = CryptDestroyHash(hHash);
1086 ok(result, "%08x\n", GetLastError());
1090 static void test_rc2(void)
1092 static const BYTE rc2_40_encrypted[16] = {
1093 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1094 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1095 static const BYTE rc2_128_encrypted[] = {
1096 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
1101 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
1103 unsigned char pbData[2000], pbHashValue[16];
1106 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1109 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1111 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1113 CRYPT_INTEGER_BLOB salt;
1115 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1116 ok(result, "%08x\n", GetLastError());
1119 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1120 ok(result, "%08x\n", GetLastError());
1122 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1123 ok(result, "%08x\n", GetLastError());
1125 dwLen = sizeof(DWORD);
1126 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1127 ok(result, "%08x\n", GetLastError());
1129 dwMode = CRYPT_MODE_CBC;
1130 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1131 ok(result, "%08x\n", GetLastError());
1133 dwLen = sizeof(DWORD);
1134 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1135 ok(result, "%08x\n", GetLastError());
1137 dwModeBits = 0xdeadbeef;
1138 dwLen = sizeof(DWORD);
1139 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1140 ok(result, "%08x\n", GetLastError());
1142 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1143 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
1144 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1145 " got %08x\n", dwModeBits);
1147 dwLen = sizeof(DWORD);
1148 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1149 ok(result, "%08x\n", GetLastError());
1151 dwLen = sizeof(DWORD);
1152 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1153 ok(result, "%08x\n", GetLastError());
1155 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1156 ok(result, "%08x\n", GetLastError());
1157 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1158 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1159 HeapFree(GetProcessHeap(), 0, pbTemp);
1161 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1162 ok(result, "%08x\n", GetLastError());
1163 /* The default salt length is always 11... */
1164 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1165 /* and the default salt is always empty. */
1166 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1167 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1168 for (i=0; i<dwLen; i++)
1169 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1170 HeapFree(GetProcessHeap(), 0, pbTemp);
1172 dwLen = sizeof(DWORD);
1173 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1175 result = CryptDestroyHash(hHash);
1176 ok(result, "%08x\n", GetLastError());
1179 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1180 ok(result, "%08x\n", GetLastError());
1182 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1184 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1185 ok(result, "%08x\n", GetLastError());
1186 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1187 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1188 HeapFree(GetProcessHeap(), 0, pbTemp);
1190 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1191 ok(result, "%08x\n", GetLastError());
1193 /* Setting the salt also succeeds... */
1194 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1195 ok(result, "setting salt failed: %08x\n", GetLastError());
1196 /* but the resulting salt length is now zero? */
1198 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1199 ok(result, "%08x\n", GetLastError());
1201 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1202 "unexpected salt length %d\n", dwLen);
1203 /* What sizes salt can I set? */
1204 salt.pbData = pbData;
1205 for (i=0; i<24; i++)
1208 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1209 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1210 /* The returned salt length is the same as the set salt length */
1211 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1212 ok(result, "%08x\n", GetLastError());
1213 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1216 SetLastError(0xdeadbeef);
1217 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1219 broken(result), /* Win9x, WinMe, NT4, W2K */
1220 "%08x\n", GetLastError());
1222 result = CryptDestroyKey(hKey);
1223 ok(result, "%08x\n", GetLastError());
1226 /* Again, but test setting the effective key len */
1227 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1229 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1231 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1233 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1234 ok(result, "%08x\n", GetLastError());
1237 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1238 ok(result, "%08x\n", GetLastError());
1240 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1241 ok(result, "%08x\n", GetLastError());
1243 SetLastError(0xdeadbeef);
1244 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1245 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1247 SetLastError(0xdeadbeef);
1248 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1249 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1251 SetLastError(0xdeadbeef);
1252 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1253 ok(!result, "CryptSetKeyParam failed: %08x\n", GetLastError());
1255 dwLen = sizeof(dwKeyLen);
1256 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1257 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1258 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1259 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1262 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1263 ok(result, "%d\n", GetLastError());
1265 dwLen = sizeof(dwKeyLen);
1266 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1267 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1268 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1269 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1271 result = CryptDestroyHash(hHash);
1272 ok(result, "%08x\n", GetLastError());
1275 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1276 ok(result, "%08x\n", GetLastError());
1278 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1279 "RC2 encryption failed!\n");
1281 /* Oddly enough this succeeds, though it should have no effect */
1283 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1284 ok(result, "%d\n", GetLastError());
1286 result = CryptDestroyKey(hKey);
1287 ok(result, "%08x\n", GetLastError());
1291 static void test_rc4(void)
1293 static const BYTE rc4[16] = {
1294 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1295 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1299 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1300 unsigned char pbData[2000], *pbTemp;
1301 unsigned char pszBuffer[256];
1304 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1307 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1309 /* rsaenh compiled without OpenSSL */
1310 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1312 CRYPT_INTEGER_BLOB salt;
1314 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1315 ok(result, "%08x\n", GetLastError());
1318 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1319 ok(result, "%08x\n", GetLastError());
1321 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1322 ok(result, "%08x\n", GetLastError());
1324 dwLen = sizeof(DWORD);
1325 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1326 ok(result, "%08x\n", GetLastError());
1328 dwLen = sizeof(DWORD);
1329 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1330 ok(result, "%08x\n", GetLastError());
1332 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1333 ok(result, "%08x\n", GetLastError());
1334 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1335 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1336 HeapFree(GetProcessHeap(), 0, pbTemp);
1338 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1339 ok(result, "%08x\n", GetLastError());
1340 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1341 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1342 HeapFree(GetProcessHeap(), 0, pbTemp);
1344 dwLen = sizeof(DWORD);
1345 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1347 result = CryptDestroyHash(hHash);
1348 ok(result, "%08x\n", GetLastError());
1351 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1352 ok(result, "%08x\n", GetLastError());
1354 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1355 ok(result, "%08x\n", GetLastError());
1357 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1359 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1360 ok(result, "%08x\n", GetLastError());
1362 /* Setting the salt also succeeds... */
1363 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1364 ok(result, "setting salt failed: %08x\n", GetLastError());
1365 /* but the resulting salt length is now zero? */
1367 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1368 ok(result, "%08x\n", GetLastError());
1370 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1371 "unexpected salt length %d\n", dwLen);
1372 /* What sizes salt can I set? */
1373 salt.pbData = pbData;
1374 for (i=0; i<24; i++)
1377 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1378 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1379 /* The returned salt length is the same as the set salt length */
1380 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1381 ok(result, "%08x\n", GetLastError());
1382 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1385 SetLastError(0xdeadbeef);
1386 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1388 broken(result), /* Win9x, WinMe, NT4, W2K */
1389 "%08x\n", GetLastError());
1391 result = CryptDestroyKey(hKey);
1392 ok(result, "%08x\n", GetLastError());
1396 static void test_hmac(void) {
1400 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1401 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1404 static const BYTE hmac[16] = {
1405 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1406 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1409 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1411 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1413 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1414 ok(result, "%08x\n", GetLastError());
1415 if (!result) return;
1417 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1418 ok(result, "%08x\n", GetLastError());
1420 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1421 ok(result, "%08x\n", GetLastError());
1423 dwLen = sizeof(abData)/sizeof(BYTE);
1424 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1425 ok(result, "%08x\n", GetLastError());
1427 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1429 result = CryptDestroyHash(hHash);
1430 ok(result, "%08x\n", GetLastError());
1432 result = CryptDestroyKey(hKey);
1433 ok(result, "%08x\n", GetLastError());
1435 /* Provoke errors */
1436 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1437 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1440 static void test_mac(void) {
1445 BYTE abData[256], abEnc[264];
1446 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1449 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1450 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1452 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1455 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1456 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1458 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1459 ok(result, "%08x\n", GetLastError());
1460 if (!result) return;
1462 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1463 ok(result, "%08x\n", GetLastError());
1465 dwLen = sizeof(abData)/sizeof(BYTE);
1466 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1467 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1469 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1471 result = CryptDestroyHash(hHash);
1472 ok(result, "%08x\n", GetLastError());
1474 result = CryptDestroyKey(hKey);
1475 ok(result, "%08x\n", GetLastError());
1477 /* Provoke errors */
1478 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1480 SetLastError(0xdeadbeef);
1481 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1482 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1483 broken(result), /* Win9x, WinMe, NT4, W2K */
1484 "%08x\n", GetLastError());
1486 result = CryptDestroyKey(hKey);
1487 ok(result, "%08x\n", GetLastError());
1490 static void test_import_private(void)
1493 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1495 static BYTE abSessionKey[148] = {
1496 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1497 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1498 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1499 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1500 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1501 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1502 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1503 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1504 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1505 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1506 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1507 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1508 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1509 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1510 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1511 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1512 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1513 0x04, 0x8c, 0x49, 0x92
1515 static BYTE abEncryptedMessage[12] = {
1516 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1517 0x1c, 0xfd, 0xde, 0x71
1520 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1521 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1523 /* rsaenh compiled without OpenSSL */
1524 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1528 dwLen = (DWORD)sizeof(abSessionKey);
1529 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1530 ok(result, "%08x\n", GetLastError());
1531 if (!result) return;
1534 dwLen = sizeof(DWORD);
1535 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1536 ok(result, "%08x\n", GetLastError());
1538 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1539 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1540 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1541 " got %08x\n", dwVal);
1543 dwLen = (DWORD)sizeof(abEncryptedMessage);
1544 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1545 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1546 "%08x, len: %d\n", GetLastError(), dwLen);
1547 CryptDestroyKey(hSessionKey);
1549 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1551 dwLen = (DWORD)sizeof(abSessionKey);
1552 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1553 ok(result, "%08x\n", GetLastError());
1554 CryptDestroyKey(hSessionKey);
1555 if (!result) return;
1557 dwLen = (DWORD)sizeof(abSessionKey);
1558 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1559 ok(result, "%08x\n", GetLastError());
1560 if (!result) return;
1562 CryptDestroyKey(hSessionKey);
1563 CryptDestroyKey(hKeyExchangeKey);
1566 static void test_verify_signature(void) {
1568 HCRYPTKEY hPubSignKey;
1569 BYTE abData[] = "Wine rocks!";
1571 BYTE abPubKey[148] = {
1572 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1573 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1574 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1575 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1576 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1577 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1578 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1579 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1580 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1581 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1582 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1583 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1584 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1585 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1586 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1587 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1588 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1589 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1590 0xe1, 0x21, 0x50, 0xac
1592 /* md2 with hash oid */
1593 BYTE abSignatureMD2[128] = {
1594 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1595 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1596 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1597 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1598 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1599 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1600 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1601 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1602 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1603 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1604 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1605 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1606 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1607 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1608 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1609 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1611 /* md2 without hash oid */
1612 BYTE abSignatureMD2NoOID[128] = {
1613 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1614 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1615 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1616 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1617 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1618 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1619 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1620 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1621 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1622 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1623 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1624 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1625 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1626 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1627 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1628 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1630 /* md4 with hash oid */
1631 BYTE abSignatureMD4[128] = {
1632 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1633 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1634 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1635 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1636 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1637 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1638 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1639 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1640 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1641 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1642 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1643 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1644 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1645 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1646 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1647 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1649 /* md4 without hash oid */
1650 BYTE abSignatureMD4NoOID[128] = {
1651 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1652 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1653 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1654 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1655 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1656 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1657 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1658 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1659 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1660 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1661 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1662 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1663 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1664 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1665 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1666 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1668 /* md5 with hash oid */
1669 BYTE abSignatureMD5[128] = {
1670 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1671 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1672 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1673 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1674 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1675 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1676 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1677 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1678 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1679 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1680 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1681 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1682 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1683 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1684 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1685 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1687 /* md5 without hash oid */
1688 BYTE abSignatureMD5NoOID[128] = {
1689 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1690 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1691 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1692 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1693 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1694 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1695 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1696 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1697 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1698 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1699 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1700 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1701 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1702 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1703 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1704 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1706 /* sha with hash oid */
1707 BYTE abSignatureSHA[128] = {
1708 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1709 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1710 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1711 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1712 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1713 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1714 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1715 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1716 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1717 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1718 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1719 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1720 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1721 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1722 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1723 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1725 /* sha without hash oid */
1726 BYTE abSignatureSHANoOID[128] = {
1727 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1728 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1729 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1730 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1731 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1732 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1733 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1734 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1735 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1736 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1737 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1738 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1739 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1740 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1741 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1742 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1745 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1746 ok(result, "%08x\n", GetLastError());
1747 if (!result) return;
1749 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1750 ok(result, "%08x\n", GetLastError());
1751 if (!result) return;
1753 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1754 ok(result, "%08x\n", GetLastError());
1755 if (!result) return;
1757 /*check that a NULL pointer signature is correctly handled*/
1758 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1759 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1760 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1763 /* check that we get a bad signature error when the signature is too short*/
1764 SetLastError(0xdeadbeef);
1765 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1766 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1767 broken(result), /* Win9x, WinMe, NT4 */
1768 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1770 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1771 ok(result, "%08x\n", GetLastError());
1772 if (!result) return;
1774 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1775 ok(result, "%08x\n", GetLastError());
1776 if (!result) return;
1778 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1779 * the OID at all. */
1780 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1781 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1782 if (result) return;*/
1784 CryptDestroyHash(hHash);
1786 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1787 ok(result, "%08x\n", GetLastError());
1788 if (!result) return;
1790 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1791 ok(result, "%08x\n", GetLastError());
1792 if (!result) return;
1794 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1795 ok(result, "%08x\n", GetLastError());
1796 if (!result) return;
1798 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1799 ok(result, "%08x\n", GetLastError());
1800 if (!result) return;
1802 CryptDestroyHash(hHash);
1804 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1805 ok(result, "%08x\n", GetLastError());
1806 if (!result) return;
1808 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1809 ok(result, "%08x\n", GetLastError());
1810 if (!result) return;
1812 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1813 ok(result, "%08x\n", GetLastError());
1814 if (!result) return;
1816 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1817 ok(result, "%08x\n", GetLastError());
1818 if (!result) return;
1820 CryptDestroyHash(hHash);
1822 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1823 ok(result, "%08x\n", GetLastError());
1824 if (!result) return;
1826 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1827 ok(result, "%08x\n", GetLastError());
1828 if (!result) return;
1830 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1831 ok(result, "%08x\n", GetLastError());
1832 if (!result) return;
1834 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1835 ok(result, "%08x\n", GetLastError());
1836 if (!result) return;
1838 CryptDestroyHash(hHash);
1839 CryptDestroyKey(hPubSignKey);
1842 static void test_rsa_encrypt(void)
1845 BYTE abData[2048] = "Wine rocks!";
1849 /* It is allowed to use the key exchange key for encryption/decryption */
1850 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1851 ok (result, "%08x\n", GetLastError());
1852 if (!result) return;
1855 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1856 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1857 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1859 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1860 ok (result, "%08x\n", GetLastError());
1861 if (!result) return;
1863 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1864 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1867 dwLen = sizeof(DWORD);
1868 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1869 ok(result, "%08x\n", GetLastError());
1871 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1872 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1873 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1874 " got %08x\n", dwVal);
1876 /* An RSA key doesn't support salt */
1877 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1878 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
1879 "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
1881 /* The key exchange key's public key may be exported.. */
1882 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1883 ok(result, "%08x\n", GetLastError());
1884 /* but its private key may not be. */
1885 SetLastError(0xdeadbeef);
1886 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1887 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1888 broken(result), /* Win9x/NT4 */
1889 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1890 /* Setting the permissions of the key exchange key isn't allowed, either. */
1891 dwVal |= CRYPT_EXPORT;
1892 SetLastError(0xdeadbeef);
1893 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1895 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1896 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1898 CryptDestroyKey(hRSAKey);
1900 /* It is not allowed to use the signature key for encryption/decryption */
1901 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1902 ok (result, "%08x\n", GetLastError());
1903 if (!result) return;
1906 dwLen = sizeof(DWORD);
1907 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1908 ok(result, "%08x\n", GetLastError());
1910 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1911 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1912 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1913 " got %08x\n", dwVal);
1915 /* The signature key's public key may also be exported.. */
1916 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1917 ok(result, "%08x\n", GetLastError());
1918 /* but its private key may not be. */
1919 SetLastError(0xdeadbeef);
1920 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1921 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1922 broken(result), /* Win9x/NT4 */
1923 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1924 /* Setting the permissions of the signature key isn't allowed, either. */
1925 dwVal |= CRYPT_EXPORT;
1926 SetLastError(0xdeadbeef);
1927 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1929 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1930 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1933 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1934 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1936 CryptDestroyKey(hRSAKey);
1939 static void test_import_export(void)
1941 DWORD dwLen, dwDataLen, dwVal;
1942 HCRYPTKEY hPublicKey, hPrivKey;
1945 BYTE emptyKey[2048], *exported_key;
1946 static BYTE abPlainPublicKey[84] = {
1947 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1948 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1949 0x01, 0x00, 0x01, 0x00, 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, 0x11, 0x11, 0x11, 0x11,
1955 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1956 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1957 0x11, 0x11, 0x11, 0x11
1959 static BYTE priv_key_with_high_bit[] = {
1960 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1961 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1962 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1963 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1964 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1965 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1966 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1967 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1968 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1969 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1970 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1971 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1972 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1973 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1974 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1975 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1976 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1977 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1978 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1979 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1980 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1981 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1982 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1983 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1984 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1985 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1986 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1987 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1988 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1989 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1990 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1991 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1992 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1993 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1994 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1995 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1996 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1997 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1998 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1999 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2000 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2001 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2002 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2003 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2004 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2005 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2006 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2007 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2008 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2009 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2010 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2011 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2012 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2013 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2014 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2015 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2016 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2017 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2018 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2019 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2020 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2021 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2022 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2023 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2024 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2025 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2026 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2027 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2028 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2029 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2030 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2031 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2032 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2033 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2034 0xb6, 0x5f, 0x01, 0x5e
2036 static const BYTE expected_exported_priv_key[] = {
2037 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2038 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2039 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2040 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2041 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2042 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2043 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2044 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2045 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2046 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2047 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2048 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2049 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2050 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2051 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2052 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2053 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2054 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2055 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2056 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2057 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2058 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2059 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2060 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2061 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2062 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2063 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2064 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2065 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2066 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2067 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2068 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2069 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2070 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2071 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2072 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2073 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2074 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2075 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2076 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2077 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2078 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2079 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2080 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2081 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2082 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2083 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2084 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2085 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2086 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2087 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2088 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2089 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2090 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2091 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2092 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2093 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2094 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2095 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2096 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2097 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2098 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2099 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2100 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2101 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2102 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2103 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2104 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2105 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2106 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2107 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2108 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2109 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2110 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2111 0xb6, 0x5f, 0x01, 0x5e
2115 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2116 ok(result, "failed to import the public key\n");
2118 dwDataLen=sizeof(algID);
2119 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2120 ok(result, "failed to get the KP_ALGID from the imported public key\n");
2121 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2124 dwDataLen = sizeof(DWORD);
2125 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2126 ok(result, "%08x\n", GetLastError());
2128 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2129 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2130 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2131 " got %08x\n", dwVal);
2132 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2133 ok(result, "failed to export the fresh imported public key\n");
2134 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2135 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2137 CryptDestroyKey(hPublicKey);
2139 result = CryptImportKey(hProv, priv_key_with_high_bit,
2140 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2141 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2143 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2144 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2145 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2146 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2148 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2150 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2152 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2153 "unexpected value\n");
2155 HeapFree(GetProcessHeap(), 0, exported_key);
2157 CryptDestroyKey(hPrivKey);
2160 static void test_import_hmac(void)
2162 /* Test cases from RFC 2202, section 3 */
2163 static const struct rfc2202_test_case {
2167 const DWORD data_len;
2170 { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2171 "\x0b\x0b\x0b\x0b", 20,
2173 "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2174 "\xf1\x46\xbe\x00" },
2176 "what do ya want for nothing?", 28,
2177 "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2178 "\x25\x9a\x7c\x79" },
2179 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2180 "\xaa\xaa\xaa\xaa", 20,
2181 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2182 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2183 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2185 "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2186 "\x63\xf1\x75\xd3" },
2187 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2188 "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2189 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2190 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2191 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2193 "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2194 "\x2d\x72\x35\xda" },
2195 { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2196 "\x0c\x0c\x0c\x0c", 20,
2197 "Test With Truncation", 20,
2198 "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2199 "\x4a\x9a\x5a\x04" },
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"
2202 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2203 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2204 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2206 "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2207 "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2208 "\xed\x40\x21\x12" },
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"
2211 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2212 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2213 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2215 "Test Using Larger Than Block-Size Key and Larger "
2216 "Than One Block-Size Data", 73,
2217 "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2218 "\xbb\xff\x1a\x91" }
2222 for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++)
2224 const struct rfc2202_test_case *test_case = &cases[i];
2225 DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2226 BYTE *blob = HeapAlloc(GetProcessHeap(), 0, size);
2230 BLOBHEADER *header = (BLOBHEADER *)blob;
2231 DWORD *key_len = (DWORD *)(header + 1);
2232 BYTE *key_bytes = (BYTE *)(key_len + 1);
2236 header->bType = PLAINTEXTKEYBLOB;
2237 header->bVersion = CUR_BLOB_VERSION;
2238 header->reserved = 0;
2239 header->aiKeyAlg = CALG_RC2;
2240 *key_len = test_case->key_len;
2241 memcpy(key_bytes, test_case->key, *key_len);
2242 result = CryptImportKey(hProv, blob, size, 0, CRYPT_IPSEC_HMAC_KEY, &key);
2243 ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
2247 HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2251 result = CryptCreateHash(hProv, CALG_HMAC, key, 0, &hash);
2252 ok(result, "CryptCreateHash failed on test case %d: %08x\n", i, GetLastError());
2253 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2254 ok(result, "CryptSetHashParam failed on test case %d: %08x\n", i, GetLastError());
2255 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2256 ok(result, "CryptHashData failed on test case %d: %08x\n", i, GetLastError());
2257 digest_size = sizeof(digest);
2258 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2259 ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
2260 ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected value on test case %d\n", i);
2261 CryptDestroyHash(hash);
2262 CryptDestroyKey(key);
2264 HeapFree(GetProcessHeap(), 0, blob);
2269 static void test_schannel_provider(void)
2272 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2273 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2276 SCHANNEL_ALG saSChannelAlg;
2277 CRYPT_DATA_BLOB data_blob;
2278 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2279 BYTE abTLS1Master[140] = {
2280 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2281 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2282 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2283 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2284 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2285 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2286 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2287 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2288 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2289 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2290 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2291 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2292 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2293 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2294 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2295 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2296 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2297 0xd3, 0x1e, 0x82, 0xb3
2299 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2300 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2301 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2302 BYTE abClientFinished[16] = "client finished";
2303 BYTE abData[16] = "Wine rocks!";
2305 static const BYTE abEncryptedData[16] = {
2306 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2307 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2309 static const BYTE abPRF[16] = {
2310 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2311 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2313 static const BYTE abMD5[16] = {
2314 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2315 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2318 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2321 win_skip("no PROV_RSA_SCHANNEL support\n");
2324 ok (result, "%08x\n", GetLastError());
2326 CryptReleaseContext(hProv, 0);
2328 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2329 ok (result, "%08x\n", GetLastError());
2330 if (!result) return;
2332 /* To get deterministic results, we import the TLS1 master secret (which
2333 * is typically generated from a random generator). Therefore, we need
2335 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2336 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2337 ok (result, "%08x\n", GetLastError());
2338 if (!result) return;
2340 dwLen = (DWORD)sizeof(abTLS1Master);
2341 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2342 ok (result, "%08x\n", GetLastError());
2343 if (!result) return;
2345 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2346 * (Keys can only be derived from hashes, not from other keys.)
2347 * The hash can't be created yet because the key doesn't have the client
2348 * random or server random set.
2350 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2351 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER,
2352 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2354 /* Setting the TLS1 client and server random parameters, as well as the
2355 * MAC and encryption algorithm parameters. */
2356 data_blob.cbData = 33;
2357 data_blob.pbData = abClientSecret;
2358 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2359 ok (result, "%08x\n", GetLastError());
2360 if (!result) return;
2362 data_blob.cbData = 33;
2363 data_blob.pbData = abServerSecret;
2364 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2365 ok (result, "%08x\n", GetLastError());
2366 if (!result) return;
2368 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2369 ok (result, "%08x\n", GetLastError());
2370 if (!result) return;
2372 /* Deriving the server write encryption key from the master hash can't
2373 * succeed before the encryption key algorithm is set.
2375 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2376 ok (!result && GetLastError() == NTE_BAD_FLAGS,
2377 "expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2379 CryptDestroyHash(hMasterHash);
2381 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2382 saSChannelAlg.Algid = CALG_DES;
2383 saSChannelAlg.cBits = 64;
2384 saSChannelAlg.dwFlags = 0;
2385 saSChannelAlg.dwReserved = 0;
2386 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2387 ok (result, "%08x\n", GetLastError());
2388 if (!result) return;
2390 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2391 saSChannelAlg.Algid = CALG_MD5;
2392 saSChannelAlg.cBits = 128;
2393 saSChannelAlg.dwFlags = 0;
2394 saSChannelAlg.dwReserved = 0;
2395 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2396 ok (result, "%08x\n", GetLastError());
2397 if (!result) return;
2399 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2400 ok (result, "%08x\n", GetLastError());
2401 if (!result) return;
2403 /* Deriving the server write encryption key from the master hash */
2404 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2405 ok (result, "%08x\n", GetLastError());
2406 if (!result) return;
2408 /* Encrypting some data with the server write encryption key and checking the result. */
2410 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2411 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2413 /* Second test case: Test the TLS1 pseudo random number function. */
2414 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2415 ok (result, "%08x\n", GetLastError());
2416 if (!result) return;
2418 /* Set the label and seed parameters for the random number function */
2419 data_blob.cbData = 36;
2420 data_blob.pbData = abHashedHandshakes;
2421 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2422 ok (result, "%08x\n", GetLastError());
2423 if (!result) return;
2425 data_blob.cbData = 15;
2426 data_blob.pbData = abClientFinished;
2427 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2428 ok (result, "%08x\n", GetLastError());
2429 if (!result) return;
2431 /* Generate some pseudo random bytes and check if they are correct. */
2432 dwLen = (DWORD)sizeof(abData);
2433 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2434 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2435 "%08x\n", GetLastError());
2437 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2438 * Hash some data with the HMAC. Compare results. */
2439 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2440 ok (result, "%08x\n", GetLastError());
2441 if (!result) return;
2443 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2444 ok (result, "%08x\n", GetLastError());
2445 if (!result) return;
2447 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2448 ok (result, "%08x\n", GetLastError());
2449 if (!result) return;
2451 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2452 ok (result, "%08x\n", GetLastError());
2453 if (!result) return;
2455 dwLen = (DWORD)sizeof(abMD5Hash);
2456 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2457 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2459 CryptDestroyHash(hHMAC);
2460 CryptDestroyHash(hTLS1PRF);
2461 CryptDestroyHash(hMasterHash);
2462 CryptDestroyKey(hServerWriteMACKey);
2463 CryptDestroyKey(hServerWriteKey);
2464 CryptDestroyKey(hRSAKey);
2465 CryptDestroyKey(hMasterSecret);
2466 CryptReleaseContext(hProv, 0);
2467 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2470 /* Test that a key can be used to encrypt data and exported, and that, when
2471 * the exported key is imported again, can be used to decrypt the original
2474 static void test_rsa_round_trip(void)
2476 static const char test_string[] = "Well this is a fine how-do-you-do.";
2478 HCRYPTKEY signKey, keyExchangeKey;
2480 BYTE data[256], *exportedKey;
2481 DWORD dataLen, keyLen;
2483 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2484 CRYPT_DELETEKEYSET);
2486 /* Generate a new key... */
2487 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2489 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2490 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2491 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2492 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2493 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2494 /* encrypt some data with it... */
2495 memcpy(data, test_string, strlen(test_string) + 1);
2496 dataLen = strlen(test_string) + 1;
2497 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2499 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2500 broken(GetLastError() == NTE_PERM /* NT4 */),
2501 "CryptEncrypt failed: %08x\n", GetLastError());
2502 /* export the key... */
2503 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2505 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2506 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2507 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2509 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2510 /* destroy the key... */
2511 CryptDestroyKey(keyExchangeKey);
2512 CryptDestroyKey(signKey);
2513 /* import the key again... */
2514 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2515 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2516 HeapFree(GetProcessHeap(), 0, exportedKey);
2517 /* and decrypt the data encrypted with the original key with the imported
2520 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2521 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2522 broken(GetLastError() == NTE_PERM /* NT4 */),
2523 "CryptDecrypt failed: %08x\n", GetLastError());
2526 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2527 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2529 CryptDestroyKey(keyExchangeKey);
2530 CryptReleaseContext(prov, 0);
2532 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2533 CRYPT_DELETEKEYSET);
2536 static void test_enum_container(void)
2538 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2540 BOOL result, fFound = FALSE;
2542 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2543 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2544 SetLastError(0xdeadbeef);
2545 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2546 ok (result, "%08x\n", GetLastError());
2547 ok (dwBufferLen == MAX_PATH + 1 ||
2548 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2549 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2551 /* If the result fits into abContainerName dwBufferLen is left untouched */
2552 dwBufferLen = (DWORD)sizeof(abContainerName);
2553 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2554 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2556 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2558 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2559 dwBufferLen = (DWORD)sizeof(abContainerName);
2560 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2562 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2565 static BYTE signBlob[] = {
2566 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2567 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2568 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2569 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2570 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2571 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2572 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2573 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2574 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2575 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2576 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2577 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2578 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2579 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2580 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2581 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2582 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2583 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2584 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2585 0xb6,0x85,0x86,0x07 };
2587 static void test_null_provider(void)
2592 DWORD keySpec, dataLen,dwParam;
2593 char szName[MAX_PATH];
2595 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2596 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2597 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2598 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2599 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2600 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2601 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2602 CRYPT_DELETEKEYSET);
2603 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2604 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2605 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2606 CRYPT_DELETEKEYSET);
2607 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2608 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2609 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2610 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2611 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2613 /* Delete the default container. */
2614 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2615 /* Once you've deleted the default container you can't open it as if it
2618 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2619 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2620 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2621 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2622 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2623 CRYPT_VERIFYCONTEXT);
2624 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2625 if (!result) return;
2626 dataLen = sizeof(keySpec);
2627 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2629 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2630 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2631 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2632 * supported, you can't get the keys from this container.
2634 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2635 ok(!result && GetLastError() == NTE_NO_KEY,
2636 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2637 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2638 ok(!result && GetLastError() == NTE_NO_KEY,
2639 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2640 result = CryptReleaseContext(prov, 0);
2641 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2642 /* You can create a new default container. */
2643 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2645 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2646 /* But you still can't get the keys (until one's been generated.) */
2647 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2648 ok(!result && GetLastError() == NTE_NO_KEY,
2649 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2650 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2651 ok(!result && GetLastError() == NTE_NO_KEY,
2652 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2653 CryptReleaseContext(prov, 0);
2654 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2656 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2657 CRYPT_DELETEKEYSET);
2658 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2659 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2660 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2661 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2662 CRYPT_VERIFYCONTEXT);
2663 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2664 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2665 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2667 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2668 if (!result) return;
2669 /* Test provider parameters getter */
2670 dataLen = sizeof(dwParam);
2671 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2672 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2673 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2674 dataLen = sizeof(dwParam);
2675 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2676 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2677 "Expected 0, got 0x%08X\n",dwParam);
2678 dataLen = sizeof(dwParam);
2679 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2680 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2681 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2682 dataLen = sizeof(keySpec);
2683 SetLastError(0xdeadbeef);
2684 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2685 if (!result && GetLastError() == NTE_BAD_TYPE)
2686 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2688 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2689 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2690 /* PP_CONTAINER parameter */
2691 dataLen = sizeof(szName);
2692 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2693 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2694 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2695 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2696 /* PP_UNIQUE_CONTAINER parameter */
2697 dataLen = sizeof(szName);
2698 SetLastError(0xdeadbeef);
2699 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2700 if (!result && GetLastError() == NTE_BAD_TYPE)
2702 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2706 char container[MAX_PATH];
2708 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2709 uniquecontainer(container);
2712 ok(dataLen == strlen(container)+1 ||
2713 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2714 "Expected a param length of 70, got %d\n", dataLen);
2715 ok(!strcmp(container, szName) ||
2716 broken(!strcmp(szName, szContainer)) /* WinME */,
2717 "Wrong container name : %s\n", szName);
2720 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2721 ok(!result && GetLastError() == NTE_NO_KEY,
2722 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2723 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2724 ok(!result && GetLastError() == NTE_NO_KEY,
2725 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2727 /* Importing a key exchange blob.. */
2728 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2730 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2731 CryptDestroyKey(key);
2732 /* allows access to the key exchange key.. */
2733 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2734 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2735 CryptDestroyKey(key);
2736 /* but not to the private key. */
2737 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2738 ok(!result && GetLastError() == NTE_NO_KEY,
2739 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2740 CryptReleaseContext(prov, 0);
2741 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2742 CRYPT_DELETEKEYSET);
2744 /* Whereas importing a sign blob.. */
2745 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2747 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2748 if (!result) return;
2749 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2750 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2751 CryptDestroyKey(key);
2752 /* doesn't allow access to the key exchange key.. */
2753 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2754 ok(!result && GetLastError() == NTE_NO_KEY,
2755 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2756 /* but does to the private key. */
2757 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2758 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2759 CryptDestroyKey(key);
2760 CryptReleaseContext(prov, 0);
2762 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2763 CRYPT_DELETEKEYSET);
2765 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2766 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2768 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2769 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2770 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2771 CryptDestroyKey(key);
2772 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2773 ok(!result, "expected CryptGetUserKey to fail\n");
2774 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2775 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2776 CryptDestroyKey(key);
2777 CryptReleaseContext(prov, 0);
2779 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2780 CRYPT_DELETEKEYSET);
2782 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2783 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2785 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2786 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2787 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2788 CryptDestroyKey(key);
2789 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2790 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2791 CryptDestroyKey(key);
2792 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2793 ok(!result, "expected CryptGetUserKey to fail\n");
2794 CryptReleaseContext(prov, 0);
2796 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2797 CRYPT_DELETEKEYSET);
2799 /* test for the bug in accessing the user key in a container
2801 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2803 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2804 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2805 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2806 CryptDestroyKey(key);
2807 CryptReleaseContext(prov,0);
2808 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2809 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2810 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2811 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2812 CryptDestroyKey(key);
2813 CryptReleaseContext(prov, 0);
2815 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2816 CRYPT_DELETEKEYSET);
2818 /* test the machine key set */
2819 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2820 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2821 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2822 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2823 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2824 CryptReleaseContext(prov, 0);
2825 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2826 CRYPT_MACHINE_KEYSET);
2827 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2828 CryptReleaseContext(prov,0);
2829 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2830 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2831 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2833 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2834 CRYPT_MACHINE_KEYSET);
2835 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2836 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2840 static void test_key_permissions(void)
2842 HCRYPTKEY hKey1, hKey2;
2846 /* Create keys that are exportable */
2847 if (!init_base_environment(CRYPT_EXPORTABLE))
2850 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2851 ok (result, "%08x\n", GetLastError());
2852 if (!result) return;
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);
2864 /* The key exchange key's public key may be exported.. */
2865 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2866 ok(result, "%08x\n", GetLastError());
2867 /* and its private key may be too. */
2868 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2869 ok(result, "%08x\n", GetLastError());
2870 /* Turning off the key's export permissions is "allowed".. */
2871 dwVal &= ~CRYPT_EXPORT;
2872 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2874 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2875 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2876 "%08x\n", GetLastError());
2877 /* but it has no effect. */
2879 dwLen = sizeof(DWORD);
2880 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2881 ok(result, "%08x\n", GetLastError());
2883 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2884 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2885 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2886 " got %08x\n", dwVal);
2887 /* Thus, changing the export flag of the key doesn't affect whether the key
2890 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2891 ok(result, "%08x\n", GetLastError());
2893 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2894 ok (result, "%08x\n", GetLastError());
2896 /* A subsequent get of the same key, into a different handle, also doesn't
2897 * show that the permissions have been changed.
2900 dwLen = sizeof(DWORD);
2901 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2902 ok(result, "%08x\n", GetLastError());
2904 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2905 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2906 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2907 " got %08x\n", dwVal);
2909 CryptDestroyKey(hKey2);
2910 CryptDestroyKey(hKey1);
2912 clean_up_base_environment();
2915 static void test_key_initialization(void)
2918 HCRYPTPROV prov1, prov2;
2919 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2921 static BYTE abSessionKey[148] = {
2922 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2923 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2924 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2925 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2926 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2927 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2928 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2929 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2930 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2931 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2932 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2933 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2934 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2935 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2936 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2937 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2938 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2939 0x04, 0x8c, 0x49, 0x92
2942 /* Like init_base_environment, but doesn't generate new keys, as they'll
2943 * be imported instead.
2945 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2947 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2949 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2951 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2952 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2953 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2955 dwLen = (DWORD)sizeof(abSessionKey);
2956 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2957 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2959 /* Once the key has been imported, subsequently acquiring a context with
2960 * the same name will allow retrieving the key.
2962 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2963 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2964 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2965 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2966 if (result) CryptDestroyKey(hKey);
2967 CryptReleaseContext(prov2, 0);
2969 CryptDestroyKey(hSessionKey);
2970 CryptDestroyKey(hKeyExchangeKey);
2971 CryptReleaseContext(prov1, 0);
2972 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2973 CRYPT_DELETEKEYSET);
2978 if (!init_base_environment(0))
2990 test_block_cipher_modes();
2991 test_import_private();
2992 test_verify_signature();
2994 test_import_export();
2996 test_enum_container();
2997 clean_up_base_environment();
2998 test_key_permissions();
2999 test_key_initialization();
3000 test_schannel_provider();
3001 test_null_provider();
3002 test_rsa_round_trip();
3003 if (!init_aes_environment())
3009 clean_up_aes_environment();