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