rsaenh/tests: Simplify broken NT4 tests.
[wine.git] / dlls / rsaenh / tests / rsaenh.c
blob2abdc552ea784ee9f3b9106ed5b5dda41521baec
1 /*
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
23 #include <string.h>
24 #include <stdio.h>
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wincrypt.h"
30 #include "winreg.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];
39 int strlen;
40 int enclen;
41 int buflen;
42 } cryptdata;
44 static const cryptdata cTestData[4] = {
45 {"abcdefghijkl",
46 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
47 12,8,16},
48 {"abcdefghij",
49 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
50 10,8,16},
51 {"abcdefgh",
52 {'a','b','c','d','e','f','g','h',0},
53 8,8,16},
54 {"abcdefghijkl",
55 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
56 12,12,16}
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
62 * 3. Append a '_'
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";
72 HKEY hkey;
73 char guid[MAX_PATH];
74 DWORD size = MAX_PATH;
75 HRESULT ret;
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);
85 RegCloseKey(hkey);
87 lstrcpyA(unique, szContainer_md5);
88 lstrcatA(unique, "_");
89 lstrcatA(unique, guid);
92 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
94 size_t i;
95 printf("%s: ",heading);
96 for(i=0;i<cb;i++)
97 printf("0x%02x,",pb[i]);
98 putchar('\n');
101 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
104 static void trace_hex(BYTE *pbData, DWORD dwLen) {
105 char szTemp[256];
106 DWORD i, j;
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]);
112 trace(szTemp);
114 for (j=0; i<dwLen; j++,i++) {
115 sprintf(szTemp+6*j, "0x%02x,\n", pbData[i]);
117 trace(szTemp);
121 static BOOL init_base_environment(DWORD dwKeyFlags)
123 HCRYPTKEY hKey;
124 BOOL result;
126 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
128 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
130 result = CryptAcquireContextA(&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 (!CryptAcquireContextA(&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");
144 return FALSE;
146 result = CryptAcquireContextA(&hProv, szContainer, szProvider, PROV_RSA_FULL,
147 CRYPT_NEWKEYSET);
148 ok(result, "%08x\n", GetLastError());
149 if (!result)
151 win_skip("Couldn't create crypto provider\n");
152 return FALSE;
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);
161 return TRUE;
164 static void clean_up_base_environment(void)
166 BOOL result;
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 CryptAcquireContextA(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
181 static BOOL init_aes_environment(void)
183 HCRYPTKEY hKey;
184 BOOL result;
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. It's different to what
192 * is defined in the SDK on Windows XP.
193 * This provider is available on Windows XP, Windows 2003 and Vista. */
195 result = CryptAcquireContextA(&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");
199 return FALSE;
201 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
203 if (!CryptAcquireContextA(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
205 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
206 if (GetLastError()!=NTE_BAD_KEYSET) return FALSE;
207 result = CryptAcquireContextA(&hProv, szContainer, NULL, PROV_RSA_AES,
208 CRYPT_NEWKEYSET);
209 ok(result, "%08x\n", GetLastError());
210 if (!result) return FALSE;
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);
218 return TRUE;
221 static void clean_up_aes_environment(void)
223 BOOL result;
225 result = CryptReleaseContext(hProv, 1);
226 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
228 CryptAcquireContextA(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
231 static void test_prov(void)
233 BOOL result;
234 DWORD dwLen, dwInc;
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");
241 else
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");
249 else
250 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
253 static void test_gen_random(void)
255 BOOL result;
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 */
264 return;
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)
277 HCRYPTHASH hHash;
278 BOOL result;
279 unsigned char pbData[2000];
280 int i;
282 *phKey = 0;
283 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
284 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
285 if (!result) {
286 /* rsaenh compiled without OpenSSL */
287 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
288 return FALSE;
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;
297 len = 2000;
298 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
299 ok(result, "%08x\n", GetLastError());
300 CryptDestroyHash(hHash);
301 return TRUE;
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,
409 0x79,0x93 };
410 unsigned char pbData[2048];
411 BOOL result;
412 HCRYPTHASH hHash, hHashClone;
413 HCRYPTPROV prov;
414 BYTE pbHashValue[36];
415 BYTE pbSigValue[128];
416 HCRYPTKEY hKeyExchangeKey;
417 DWORD hashlen, len, error, cryptflags;
418 int i;
420 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
422 /* MD2 Hashing */
423 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
424 if (!result) {
425 /* rsaenh compiled without OpenSSL */
426 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
427 } else {
428 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
429 ok(result, "%08x\n", GetLastError());
431 len = sizeof(DWORD);
432 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
433 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
435 len = 16;
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());
445 /* MD4 Hashing */
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 && GetLastError() == NTE_BAD_FLAGS, "%08x\n", GetLastError());
452 cryptflags = CRYPT_USERDATA;
453 result = CryptHashData(hHash, pbData, sizeof(pbData), cryptflags);
454 if (!result && GetLastError() == NTE_BAD_FLAGS) /* <= NT4 */
456 cryptflags &= ~CRYPT_USERDATA;
457 ok(broken(1), "Failed to support CRYPT_USERDATA flag\n");
458 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
460 ok(result, "%08x\n", GetLastError());
462 len = sizeof(DWORD);
463 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
464 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
466 len = 16;
467 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
468 ok(result, "%08x\n", GetLastError());
470 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
472 result = CryptDestroyHash(hHash);
473 ok(result, "%08x\n", GetLastError());
475 /* MD5 Hashing */
476 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
477 ok(result, "%08x\n", GetLastError());
479 len = sizeof(DWORD);
480 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
481 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
483 result = CryptHashData(hHash, pbData, sizeof(pbData), ~0);
484 ok(!result && GetLastError() == NTE_BAD_FLAGS, "%08x\n", GetLastError());
486 result = CryptHashData(hHash, pbData, sizeof(pbData), cryptflags);
487 ok(result, "%08x\n", GetLastError());
489 len = 16;
490 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
491 ok(result, "%08x\n", GetLastError());
493 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
495 result = CryptDestroyHash(hHash);
496 ok(result, "%08x\n", GetLastError());
498 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
499 ok(result, "%08x\n", GetLastError());
501 /* The hash is available even if CryptHashData hasn't been called */
502 len = 16;
503 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
504 ok(result, "%08x\n", GetLastError());
506 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
508 /* It's also stable: getting it twice results in the same value */
509 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
510 ok(result, "%08x\n", GetLastError());
512 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
514 /* Can't add data after the hash been retrieved */
515 SetLastError(0xdeadbeef);
516 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
517 ok(!result, "Expected failure\n");
518 ok(GetLastError() == NTE_BAD_HASH_STATE ||
519 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
520 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
522 /* You can still retrieve the hash, its value just hasn't changed */
523 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
524 ok(result, "%08x\n", GetLastError());
526 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
528 result = CryptDestroyHash(hHash);
529 ok(result, "%08x\n", GetLastError());
531 /* SHA1 Hashing */
532 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
533 ok(result, "%08x\n", GetLastError());
535 result = CryptHashData(hHash, pbData, 5, cryptflags);
536 ok(result, "%08x\n", GetLastError());
538 if(pCryptDuplicateHash) {
539 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
540 ok(result, "%08x\n", GetLastError());
542 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
543 ok(result, "%08x\n", GetLastError());
545 len = sizeof(DWORD);
546 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
547 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
549 len = 20;
550 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
551 ok(result, "%08x\n", GetLastError());
553 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
555 result = CryptDestroyHash(hHashClone);
556 ok(result, "%08x\n", GetLastError());
559 result = CryptDestroyHash(hHash);
560 ok(result, "%08x\n", GetLastError());
562 /* The SHA-2 variants aren't supported in the RSA full provider */
563 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
564 ok(!result && GetLastError() == NTE_BAD_ALGID,
565 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
566 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
567 ok(!result && GetLastError() == NTE_BAD_ALGID,
568 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
569 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
570 ok(!result && GetLastError() == NTE_BAD_ALGID,
571 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
573 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
574 ok(result, "CryptAcquireContextA failed 0x%08x\n", GetLastError());
576 result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash);
577 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
579 /* release provider before using the hash */
580 result = CryptReleaseContext(prov, 0);
581 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
583 SetLastError(0xdeadbeef);
584 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
585 error = GetLastError();
586 ok(!result, "CryptHashData succeeded\n");
587 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
589 SetLastError(0xdeadbeef);
590 result = CryptDestroyHash(hHash);
591 error = GetLastError();
592 ok(!result, "CryptDestroyHash succeeded\n");
593 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
595 if (!pCryptDuplicateHash)
597 win_skip("CryptDuplicateHash is not available\n");
598 return;
601 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
602 ok(result, "CryptAcquireContextA failed 0x%08x\n", GetLastError());
604 result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
605 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
607 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
608 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
610 result = pCryptDuplicateHash(hHash, NULL, 0, &hHashClone);
611 ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
613 len = 20;
614 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
615 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
617 /* add data after duplicating the hash */
618 result = CryptHashData(hHash, (const BYTE *)"more data", sizeof("more data"), 0);
619 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
621 result = CryptDestroyHash(hHash);
622 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
624 result = CryptDestroyHash(hHashClone);
625 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
627 result = CryptReleaseContext(prov, 0);
628 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
630 /* Test CALG_SSL3_SHAMD5 */
631 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
632 ok(result, "CryptAcquireContextA failed 0x%08x\n", GetLastError());
634 /* Step 1: create an MD5 hash of the data */
635 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
636 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
637 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
638 ok(result, "%08x\n", GetLastError());
639 len = 16;
640 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
641 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
642 result = CryptDestroyHash(hHash);
643 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
644 /* Step 2: create a SHA1 hash of the data */
645 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
646 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
647 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
648 ok(result, "%08x\n", GetLastError());
649 len = 20;
650 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue + 16, &len, 0);
651 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
652 result = CryptDestroyHash(hHash);
653 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
654 /* Step 3: create a CALG_SSL3_SHAMD5 hash handle */
655 result = CryptCreateHash(hProv, CALG_SSL3_SHAMD5, 0, 0, &hHash);
656 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
657 /* Test that CryptHashData fails on this hash */
658 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
659 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
660 result = CryptSetHashParam(hHash, HP_HASHVAL, pbHashValue, 0);
661 ok(result, "%08x\n", GetLastError());
662 len = (DWORD)sizeof(abPlainPrivateKey);
663 result = CryptImportKey(hProv, abPlainPrivateKey, len, 0, 0, &hKeyExchangeKey);
664 ok(result, "%08x\n", GetLastError());
665 len = 0;
666 result = CryptSignHashA(hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &len);
667 ok(result, "%08x\n", GetLastError());
668 ok(len == 128, "expected len 128, got %d\n", len);
669 result = CryptSignHashA(hHash, AT_KEYEXCHANGE, NULL, 0, pbSigValue, &len);
670 ok(result, "%08x\n", GetLastError());
671 ok(!memcmp(pbSigValue, signed_ssl3_shamd5_hash, len), "unexpected value\n");
672 if (len != 128 || memcmp(pbSigValue, signed_ssl3_shamd5_hash, len))
674 printBytes("expected", signed_ssl3_shamd5_hash,
675 sizeof(signed_ssl3_shamd5_hash));
676 printBytes("got", pbSigValue, len);
678 result = CryptDestroyKey(hKeyExchangeKey);
679 ok(result, "CryptDestroyKey failed 0x%08x\n", GetLastError());
680 result = CryptDestroyHash(hHash);
681 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
682 result = CryptReleaseContext(prov, 0);
683 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
686 static void test_block_cipher_modes(void)
688 static const BYTE plain[23] = {
689 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
690 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
691 static const BYTE ecb[24] = {
692 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
693 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
694 static const BYTE cbc[24] = {
695 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
696 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
697 static const BYTE cfb[24] = {
698 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
699 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
700 HCRYPTKEY hKey;
701 BOOL result;
702 BYTE abData[24];
703 DWORD dwMode, dwLen;
705 result = derive_key(CALG_RC2, &hKey, 40);
706 if (!result) return;
708 memcpy(abData, plain, sizeof(plain));
710 /* test default chaining mode */
711 dwMode = 0xdeadbeef;
712 dwLen = sizeof(dwMode);
713 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
714 ok(result, "%08x\n", GetLastError());
715 ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining mode\n");
717 dwMode = CRYPT_MODE_ECB;
718 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
719 ok(result, "%08x\n", GetLastError());
721 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
722 ok(result, "%08x\n", GetLastError());
723 ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
725 dwLen = 23;
726 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
727 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
728 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
730 SetLastError(ERROR_SUCCESS);
731 dwLen = 23;
732 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
733 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
734 "%08x, dwLen: %d\n", GetLastError(), dwLen);
736 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
737 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
738 "%08x, dwLen: %d\n", GetLastError(), dwLen);
740 dwMode = CRYPT_MODE_CBC;
741 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
742 ok(result, "%08x\n", GetLastError());
744 dwLen = 23;
745 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
746 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
747 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
749 dwLen = 23;
750 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
751 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
752 "%08x, dwLen: %d\n", GetLastError(), dwLen);
754 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
755 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
756 "%08x, dwLen: %d\n", GetLastError(), dwLen);
758 dwMode = CRYPT_MODE_CFB;
759 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
760 ok(result, "%08x\n", GetLastError());
762 dwLen = 16;
763 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
764 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
766 dwLen = 7;
767 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
768 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
769 "%08x, dwLen: %d\n", GetLastError(), dwLen);
771 dwLen = 8;
772 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
773 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
775 dwLen = 16;
776 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
777 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
778 "%08x, dwLen: %d\n", GetLastError(), dwLen);
780 dwMode = CRYPT_MODE_OFB;
781 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
782 ok(result, "%08x\n", GetLastError());
784 dwLen = 23;
785 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
786 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
788 CryptDestroyKey(hKey);
791 static void test_3des112(void)
793 HCRYPTKEY hKey;
794 BOOL result;
795 DWORD dwLen;
796 unsigned char pbData[16], enc_data[16], bad_data[16];
797 static const BYTE des112[16] = {
798 0x8e, 0x0c, 0x3c, 0xa3, 0x05, 0x88, 0x5f, 0x7a,
799 0x32, 0xa1, 0x06, 0x52, 0x64, 0xd2, 0x44, 0x1c };
800 int i;
802 result = derive_key(CALG_3DES_112, &hKey, 0);
803 if (!result) {
804 /* rsaenh compiled without OpenSSL */
805 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
806 return;
809 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
811 dwLen = 13;
812 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
813 ok(result, "%08x\n", GetLastError());
815 ok(!memcmp(pbData, des112, sizeof(des112)), "3DES_112 encryption failed!\n");
817 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
818 ok(result, "%08x\n", GetLastError());
820 for (i=0; i<4; i++)
822 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
824 dwLen = cTestData[i].enclen;
825 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
826 ok(result, "%08x\n", GetLastError());
827 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
828 memcpy(enc_data, pbData, cTestData[i].buflen);
830 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
831 ok(result, "%08x\n", GetLastError());
832 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
833 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
834 if((dwLen != cTestData[i].enclen) ||
835 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
837 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
838 printBytes("got",pbData,dwLen);
841 /* Test bad data:
842 Decrypting a block of bad data with Final = TRUE should restore the
843 initial state of the key as well as decrypting a block of good data.
846 /* Changing key state by setting Final = FALSE */
847 dwLen = cTestData[i].buflen;
848 memcpy(pbData, enc_data, cTestData[i].buflen);
849 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
850 ok(result, "%08x\n", GetLastError());
852 /* Restoring key state by decrypting bad_data with Final = TRUE */
853 memcpy(bad_data, enc_data, cTestData[i].buflen);
854 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
855 SetLastError(0xdeadbeef);
856 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
857 ok(!result, "CryptDecrypt should failed!\n");
858 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
859 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
860 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
862 /* Checking key state */
863 dwLen = cTestData[i].buflen;
864 memcpy(pbData, enc_data, cTestData[i].buflen);
865 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
866 ok(result, "%08x\n", GetLastError());
867 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
868 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
869 if((dwLen != cTestData[i].enclen) ||
870 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
872 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
873 printBytes("got",pbData,dwLen);
876 result = CryptDestroyKey(hKey);
877 ok(result, "%08x\n", GetLastError());
880 static void test_des(void)
882 HCRYPTKEY hKey;
883 BOOL result;
884 DWORD dwLen, dwMode;
885 unsigned char pbData[16], enc_data[16], bad_data[16];
886 static const BYTE des[16] = {
887 0x58, 0x86, 0x42, 0x46, 0x65, 0x4b, 0x92, 0x62,
888 0xcf, 0x0f, 0x65, 0x37, 0x43, 0x7a, 0x82, 0xb9 };
889 static const BYTE des_old_behavior[16] = {
890 0xb0, 0xfd, 0x11, 0x69, 0x76, 0xb1, 0xa1, 0x03,
891 0xf7, 0xbc, 0x23, 0xaa, 0xd4, 0xc1, 0xc9, 0x55 };
892 int i;
894 result = derive_key(CALG_DES, &hKey, 0);
895 if (!result) {
896 /* rsaenh compiled without OpenSSL */
897 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
898 return;
901 dwMode = CRYPT_MODE_ECB;
902 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
903 ok(result, "%08x\n", GetLastError());
905 dwLen = sizeof(DWORD);
906 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
907 ok(result, "%08x\n", GetLastError());
909 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
911 dwLen = 13;
912 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
913 ok(result, "%08x\n", GetLastError());
915 ok(!memcmp(pbData, des, sizeof(des)), "DES encryption failed!\n");
917 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
918 ok(result, "%08x\n", GetLastError());
920 for (i=0; i<4; i++)
922 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
924 dwLen = cTestData[i].enclen;
925 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
926 ok(result, "%08x\n", GetLastError());
927 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
928 memcpy(enc_data, pbData, cTestData[i].buflen);
930 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
931 ok(result, "%08x\n", GetLastError());
932 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
933 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
934 if((dwLen != cTestData[i].enclen) ||
935 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
937 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
938 printBytes("got",pbData,dwLen);
941 /* Test bad data:
942 Decrypting a block of bad data with Final = TRUE should restore the
943 initial state of the key as well as decrypting a block of good data.
946 /* Changing key state by setting Final = FALSE */
947 dwLen = cTestData[i].buflen;
948 memcpy(pbData, enc_data, cTestData[i].buflen);
949 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
950 ok(result, "%08x\n", GetLastError());
952 /* Restoring key state by decrypting bad_data with Final = TRUE */
953 memcpy(bad_data, enc_data, cTestData[i].buflen);
954 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
955 SetLastError(0xdeadbeef);
956 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
957 ok(!result, "CryptDecrypt should failed!\n");
958 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
959 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
960 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
962 /* Checking key state */
963 dwLen = cTestData[i].buflen;
964 memcpy(pbData, enc_data, cTestData[i].buflen);
965 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
966 ok(result, "%08x\n", GetLastError());
967 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
968 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
969 if((dwLen != cTestData[i].enclen) ||
970 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
972 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
973 printBytes("got",pbData,dwLen);
977 result = CryptDestroyKey(hKey);
978 ok(result, "%08x\n", GetLastError());
980 /* Windows >= XP changed the way DES keys are derived, this test ensures we don't break that */
981 derive_key(CALG_DES, &hKey, 56);
983 dwMode = CRYPT_MODE_ECB;
984 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
985 ok(result, "%08x\n", GetLastError());
987 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
989 dwLen = 13;
990 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
991 ok(result, "%08x\n", GetLastError());
993 ok(!memcmp(pbData, des, sizeof(des)) || broken(!memcmp(pbData, des_old_behavior, sizeof(des))) /* <= 2000 */,
994 "DES encryption failed!\n");
996 result = CryptDestroyKey(hKey);
997 ok(result, "%08x\n", GetLastError());
1000 static void test_3des(void)
1002 HCRYPTKEY hKey;
1003 BOOL result;
1004 DWORD dwLen;
1005 unsigned char pbData[16], enc_data[16], bad_data[16];
1006 static const BYTE des3[16] = {
1007 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
1008 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
1009 int i;
1011 result = derive_key(CALG_3DES, &hKey, 0);
1012 if (!result) return;
1014 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
1016 dwLen = 13;
1017 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
1018 ok(result, "%08x\n", GetLastError());
1020 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
1022 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1023 ok(result, "%08x\n", GetLastError());
1025 for (i=0; i<4; i++)
1027 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
1029 dwLen = cTestData[i].enclen;
1030 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
1031 ok(result, "%08x\n", GetLastError());
1032 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1033 memcpy(enc_data, pbData, cTestData[i].buflen);
1035 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1036 ok(result, "%08x\n", GetLastError());
1037 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1038 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
1039 if((dwLen != cTestData[i].enclen) ||
1040 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1042 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1043 printBytes("got",pbData,dwLen);
1046 /* Test bad data:
1047 Decrypting a block of bad data with Final = TRUE should restore the
1048 initial state of the key as well as decrypting a block of good data.
1051 /* Changing key state by setting Final = FALSE */
1052 dwLen = cTestData[i].buflen;
1053 memcpy(pbData, enc_data, cTestData[i].buflen);
1054 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
1055 ok(result, "%08x\n", GetLastError());
1057 /* Restoring key state by decrypting bad_data with Final = TRUE */
1058 memcpy(bad_data, enc_data, cTestData[i].buflen);
1059 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
1060 SetLastError(0xdeadbeef);
1061 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
1062 ok(!result, "CryptDecrypt should failed!\n");
1063 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
1064 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1065 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1067 /* Checking key state */
1068 dwLen = cTestData[i].buflen;
1069 memcpy(pbData, enc_data, cTestData[i].buflen);
1070 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1071 ok(result, "%08x\n", GetLastError());
1072 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1073 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1074 if((dwLen != cTestData[i].enclen) ||
1075 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1077 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1078 printBytes("got",pbData,dwLen);
1081 result = CryptDestroyKey(hKey);
1082 ok(result, "%08x\n", GetLastError());
1085 static void test_aes(int keylen)
1087 HCRYPTKEY hKey;
1088 BOOL result;
1089 DWORD dwLen, dwMode;
1090 unsigned char pbData[48], enc_data[16], bad_data[16];
1091 int i;
1092 static const BYTE aes_plain[32] = {
1093 "AES Test With 2 Blocks Of Data." };
1094 static const BYTE aes_cbc_enc[3][48] = {
1095 /* 128 bit key encrypted text */
1096 { 0xfe, 0x85, 0x3b, 0xe1, 0xf5, 0xe1, 0x58, 0x75, 0xd5, 0xa9, 0x74, 0xe3, 0x09, 0xea, 0xa5, 0x04,
1097 0x23, 0x35, 0xa2, 0x3b, 0x5c, 0xf1, 0x6c, 0x6f, 0xb9, 0xcd, 0x64, 0x06, 0x3e, 0x41, 0x83, 0xef,
1098 0x2a, 0xfe, 0xea, 0xb5, 0x6c, 0x17, 0x20, 0x79, 0x8c, 0x51, 0x3e, 0x56, 0xed, 0xe1, 0x47, 0x68 },
1099 /* 192 bit key encrypted text */
1100 { 0x6b, 0xf0, 0xfd, 0x32, 0xee, 0xc6, 0x06, 0x13, 0xa8, 0xe6, 0x3c, 0x81, 0x85, 0xb8, 0x2e, 0xa1,
1101 0xd4, 0x3b, 0xe8, 0x22, 0xa5, 0x74, 0x4a, 0xbe, 0x9d, 0xcf, 0xcc, 0x37, 0x26, 0x19, 0x5a, 0xd1,
1102 0x7f, 0x76, 0xbf, 0x94, 0x28, 0xce, 0x27, 0x21, 0x61, 0x87, 0xeb, 0xb9, 0x8b, 0xa8, 0xb4, 0x57 },
1103 /* 256 bit key encrypted text */
1104 { 0x20, 0x57, 0x17, 0x0b, 0x17, 0x76, 0xd8, 0x3b, 0x26, 0x90, 0x8b, 0x4c, 0xf2, 0x00, 0x79, 0x33,
1105 0x29, 0x2b, 0x13, 0x9c, 0xe2, 0x95, 0x09, 0xc1, 0xcd, 0x20, 0x87, 0x22, 0x32, 0x70, 0x9d, 0x75,
1106 0x9a, 0x94, 0xf5, 0x76, 0x5c, 0xb1, 0x62, 0x2c, 0xe1, 0x76, 0x7c, 0x86, 0x73, 0xe6, 0x7a, 0x23 }
1108 switch (keylen)
1110 case 256:
1111 result = derive_key(CALG_AES_256, &hKey, 0);
1112 i = 2;
1113 break;
1114 case 192:
1115 result = derive_key(CALG_AES_192, &hKey, 0);
1116 i = 1;
1117 break;
1118 default:
1119 case 128:
1120 result = derive_key(CALG_AES_128, &hKey, 0);
1121 i = 0;
1122 break;
1124 if (!result) return;
1126 dwLen = sizeof(aes_plain);
1127 memcpy(pbData, aes_plain, dwLen);
1128 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, sizeof(pbData));
1129 ok(result, "Expected OK, got last error %d\n", GetLastError());
1130 ok(dwLen == 48, "Expected dwLen 48, got %d\n", dwLen);
1131 todo_wine
1132 ok(!memcmp(aes_cbc_enc[i], pbData, dwLen), "Expected equal data sequences\n");
1134 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1135 ok(result && dwLen == 32 && !memcmp(aes_plain, pbData, dwLen),
1136 "%08x, dwLen: %d\n", GetLastError(), dwLen);
1138 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
1140 /* Does AES provider support salt? */
1141 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1142 ok((!result && GetLastError() == NTE_BAD_KEY) || result /* Win7 */,
1143 "expected NTE_BAD_KEY, got %08x\n", GetLastError());
1144 if (result)
1145 ok(!dwLen, "unexpected salt length %d\n", dwLen);
1147 /* test default chaining mode */
1148 dwMode = 0xdeadbeef;
1149 dwLen = sizeof(dwMode);
1150 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1151 ok(result, "%08x\n", GetLastError());
1152 todo_wine
1153 ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining\n");
1155 dwLen = 13;
1156 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
1157 ok(result, "%08x\n", GetLastError());
1159 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1160 ok(result, "%08x\n", GetLastError());
1162 for (i=0; i<4; i++)
1164 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
1166 dwLen = cTestData[i].enclen;
1167 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
1168 ok(result, "%08x\n", GetLastError());
1169 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1170 memcpy(enc_data, pbData, cTestData[i].buflen);
1172 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1173 ok(result, "%08x\n", GetLastError());
1174 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1175 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1176 if((dwLen != cTestData[i].enclen) ||
1177 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1179 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1180 printBytes("got",pbData,dwLen);
1183 /* Test bad data:
1184 Decrypting a block of bad data with Final = TRUE should restore the
1185 initial state of the key as well as decrypting a block of good data.
1188 /* Changing key state by setting Final = FALSE */
1189 dwLen = cTestData[i].buflen;
1190 memcpy(pbData, enc_data, cTestData[i].buflen);
1191 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
1192 ok(result, "%08x\n", GetLastError());
1194 /* Restoring key state by decrypting bad_data with Final = TRUE */
1195 memcpy(bad_data, enc_data, cTestData[i].buflen);
1196 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
1197 SetLastError(0xdeadbeef);
1198 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
1199 ok(!result, "CryptDecrypt should failed!\n");
1200 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
1201 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1202 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1204 /* Checking key state */
1205 dwLen = cTestData[i].buflen;
1206 memcpy(pbData, enc_data, cTestData[i].buflen);
1207 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1208 ok(result, "%08x\n", GetLastError());
1209 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1210 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1211 if((dwLen != cTestData[i].enclen) ||
1212 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1214 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1215 printBytes("got",pbData,dwLen);
1218 result = CryptDestroyKey(hKey);
1219 ok(result, "%08x\n", GetLastError());
1222 static void test_sha2(void)
1224 static const unsigned char sha256hash[32] = {
1225 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
1226 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
1227 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
1228 0x1a, 0x08
1230 static const unsigned char sha384hash[48] = {
1231 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
1232 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
1233 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
1234 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
1235 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
1237 static const unsigned char sha512hash[64] = {
1238 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1239 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1240 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1241 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1242 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1243 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1244 0xb7, 0xf4, 0x81, 0xd4
1246 unsigned char pbData[2048];
1247 BOOL result;
1248 HCRYPTHASH hHash;
1249 BYTE pbHashValue[64];
1250 DWORD hashlen, len;
1251 int i;
1253 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1255 /* SHA-256 hash */
1256 SetLastError(0xdeadbeef);
1257 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1258 if (!result && GetLastError() == NTE_BAD_ALGID) {
1259 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1260 return;
1262 ok(result, "%08x\n", GetLastError());
1263 if (result) {
1264 len = sizeof(DWORD);
1265 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1266 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1268 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1269 ok(result, "%08x\n", GetLastError());
1271 len = 32;
1272 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1273 ok(result, "%08x\n", GetLastError());
1275 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1277 result = CryptDestroyHash(hHash);
1278 ok(result, "%08x\n", GetLastError());
1281 /* SHA-384 hash */
1282 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1283 ok(result, "%08x\n", GetLastError());
1284 if (result) {
1285 len = sizeof(DWORD);
1286 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1287 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1289 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1290 ok(result, "%08x\n", GetLastError());
1292 len = 48;
1293 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1294 ok(result, "%08x\n", GetLastError());
1296 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1298 result = CryptDestroyHash(hHash);
1299 ok(result, "%08x\n", GetLastError());
1302 /* SHA-512 hash */
1303 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1304 ok(result, "%08x\n", GetLastError());
1305 if (result) {
1306 len = sizeof(DWORD);
1307 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1308 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1310 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1311 ok(result, "%08x\n", GetLastError());
1313 len = 64;
1314 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1315 ok(result, "%08x\n", GetLastError());
1317 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1319 result = CryptDestroyHash(hHash);
1320 ok(result, "%08x\n", GetLastError());
1324 static void test_rc2(void)
1326 static const BYTE rc2_40_encrypted[16] = {
1327 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1328 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1329 static const BYTE rc2_128_encrypted[] = {
1330 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
1331 0xb6,0x66 };
1332 HCRYPTHASH hHash;
1333 HCRYPTKEY hKey;
1334 BOOL result;
1335 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
1336 BYTE *pbTemp;
1337 unsigned char pbData[2000], pbHashValue[16];
1338 int i;
1340 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1342 /* MD2 Hashing */
1343 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1344 if (!result) {
1345 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1346 } else {
1347 CRYPT_INTEGER_BLOB salt;
1349 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1350 ok(result, "%08x\n", GetLastError());
1352 dwLen = 16;
1353 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1354 ok(result, "%08x\n", GetLastError());
1356 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1357 ok(result, "%08x\n", GetLastError());
1359 dwLen = sizeof(DWORD);
1360 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1361 ok(result, "%08x\n", GetLastError());
1363 /* test default chaining mode */
1364 dwMode = 0xdeadbeef;
1365 dwLen = sizeof(dwMode);
1366 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1367 ok(result, "%08x\n", GetLastError());
1368 ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining mode\n");
1370 dwMode = CRYPT_MODE_CBC;
1371 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1372 ok(result, "%08x\n", GetLastError());
1374 dwLen = sizeof(DWORD);
1375 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1376 ok(result, "%08x\n", GetLastError());
1378 dwModeBits = 0xdeadbeef;
1379 dwLen = sizeof(DWORD);
1380 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1381 ok(result, "%08x\n", GetLastError());
1382 ok(dwModeBits ==
1383 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1384 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
1385 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1386 " got %08x\n", dwModeBits);
1388 dwLen = sizeof(DWORD);
1389 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1390 ok(result, "%08x\n", GetLastError());
1392 dwLen = sizeof(DWORD);
1393 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1394 ok(result, "%08x\n", GetLastError());
1396 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1397 ok(result, "%08x\n", GetLastError());
1398 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1399 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1400 HeapFree(GetProcessHeap(), 0, pbTemp);
1402 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1403 ok(result, "%08x\n", GetLastError());
1404 /* The default salt length is always 11... */
1405 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1406 /* and the default salt is always empty. */
1407 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1408 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1409 for (i=0; i<dwLen; i++)
1410 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1411 HeapFree(GetProcessHeap(), 0, pbTemp);
1413 dwLen = sizeof(DWORD);
1414 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1416 result = CryptDestroyHash(hHash);
1417 ok(result, "%08x\n", GetLastError());
1419 dwDataLen = 13;
1420 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1421 ok(result, "%08x\n", GetLastError());
1423 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1425 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1426 ok(result, "%08x\n", GetLastError());
1427 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1428 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1429 HeapFree(GetProcessHeap(), 0, pbTemp);
1431 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1432 ok(result, "%08x\n", GetLastError());
1434 /* Setting the salt also succeeds... */
1435 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1436 ok(result, "setting salt failed: %08x\n", GetLastError());
1437 /* but the resulting salt length is now zero? */
1438 dwLen = 0;
1439 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1440 ok(result, "%08x\n", GetLastError());
1441 ok(dwLen == 0 ||
1442 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1443 "unexpected salt length %d\n", dwLen);
1444 /* What sizes salt can I set? */
1445 salt.pbData = pbData;
1446 for (i=0; i<24; i++)
1448 salt.cbData = i;
1449 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1450 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1451 /* The returned salt length is the same as the set salt length */
1452 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1453 ok(result, "%08x\n", GetLastError());
1454 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1456 salt.cbData = 25;
1457 SetLastError(0xdeadbeef);
1458 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1459 ok(!result ||
1460 broken(result), /* Win9x, WinMe, NT4, W2K */
1461 "%08x\n", GetLastError());
1463 result = CryptDestroyKey(hKey);
1464 ok(result, "%08x\n", GetLastError());
1467 /* Again, but test setting the effective key len */
1468 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1470 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1471 if (!result) {
1472 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1473 } else {
1474 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1475 ok(result, "%08x\n", GetLastError());
1477 dwLen = 16;
1478 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1479 ok(result, "%08x\n", GetLastError());
1481 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1482 ok(result, "%08x\n", GetLastError());
1484 SetLastError(0xdeadbeef);
1485 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1486 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1487 dwKeyLen = 0;
1488 SetLastError(0xdeadbeef);
1489 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1490 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1491 dwKeyLen = 1025;
1492 SetLastError(0xdeadbeef);
1493 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1494 ok(!result, "CryptSetKeyParam failed: %08x\n", GetLastError());
1496 dwLen = sizeof(dwKeyLen);
1497 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1498 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1499 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1500 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1502 dwKeyLen = 128;
1503 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1504 ok(result, "%d\n", GetLastError());
1506 dwLen = sizeof(dwKeyLen);
1507 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1508 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1509 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1510 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1512 result = CryptDestroyHash(hHash);
1513 ok(result, "%08x\n", GetLastError());
1515 dwDataLen = 13;
1516 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1517 ok(result, "%08x\n", GetLastError());
1519 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1520 "RC2 encryption failed!\n");
1522 /* Oddly enough this succeeds, though it should have no effect */
1523 dwKeyLen = 40;
1524 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1525 ok(result, "%d\n", GetLastError());
1527 result = CryptDestroyKey(hKey);
1528 ok(result, "%08x\n", GetLastError());
1532 static void test_rc4(void)
1534 static const BYTE rc4[16] = {
1535 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1536 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1537 BOOL result;
1538 HCRYPTHASH hHash;
1539 HCRYPTKEY hKey;
1540 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1541 unsigned char pbData[2000], *pbTemp;
1542 unsigned char pszBuffer[256];
1543 int i;
1545 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1547 /* MD2 Hashing */
1548 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1549 if (!result) {
1550 /* rsaenh compiled without OpenSSL */
1551 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1552 } else {
1553 CRYPT_INTEGER_BLOB salt;
1555 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1556 ok(result, "%08x\n", GetLastError());
1558 dwLen = 16;
1559 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1560 ok(result, "%08x\n", GetLastError());
1562 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1563 ok(result, "%08x\n", GetLastError());
1565 dwLen = sizeof(DWORD);
1566 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1567 ok(result, "%08x\n", GetLastError());
1569 dwLen = sizeof(DWORD);
1570 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1571 ok(result, "%08x\n", GetLastError());
1573 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1574 ok(result, "%08x\n", GetLastError());
1575 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1576 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1577 HeapFree(GetProcessHeap(), 0, pbTemp);
1579 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1580 ok(result, "%08x\n", GetLastError());
1581 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1582 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1583 HeapFree(GetProcessHeap(), 0, pbTemp);
1585 dwLen = sizeof(DWORD);
1586 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1588 result = CryptDestroyHash(hHash);
1589 ok(result, "%08x\n", GetLastError());
1591 dwDataLen = 16;
1592 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1593 ok(result, "%08x\n", GetLastError());
1594 dwDataLen = 16;
1595 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1596 ok(result, "%08x\n", GetLastError());
1598 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1600 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1601 ok(result, "%08x\n", GetLastError());
1603 /* Setting the salt also succeeds... */
1604 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1605 ok(result, "setting salt failed: %08x\n", GetLastError());
1606 /* but the resulting salt length is now zero? */
1607 dwLen = 0;
1608 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1609 ok(result, "%08x\n", GetLastError());
1610 ok(dwLen == 0 ||
1611 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1612 "unexpected salt length %d\n", dwLen);
1613 /* What sizes salt can I set? */
1614 salt.pbData = pbData;
1615 for (i=0; i<24; i++)
1617 salt.cbData = i;
1618 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1619 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1620 /* The returned salt length is the same as the set salt length */
1621 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1622 ok(result, "%08x\n", GetLastError());
1623 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1625 salt.cbData = 25;
1626 SetLastError(0xdeadbeef);
1627 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1628 ok(!result ||
1629 broken(result), /* Win9x, WinMe, NT4, W2K */
1630 "%08x\n", GetLastError());
1632 result = CryptDestroyKey(hKey);
1633 ok(result, "%08x\n", GetLastError());
1637 static void test_hmac(void) {
1638 HCRYPTKEY hKey;
1639 HCRYPTHASH hHash;
1640 BOOL result;
1641 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1642 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1643 DWORD dwLen;
1644 BYTE abData[256];
1645 static const BYTE hmac[16] = {
1646 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1647 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1648 int i;
1650 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1652 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1654 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1655 ok(result, "%08x\n", GetLastError());
1656 if (!result) return;
1658 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1659 ok(result, "%08x\n", GetLastError());
1661 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1662 ok(result, "%08x\n", GetLastError());
1664 dwLen = sizeof(abData)/sizeof(BYTE);
1665 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1666 ok(result, "%08x\n", GetLastError());
1668 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1670 result = CryptDestroyHash(hHash);
1671 ok(result, "%08x\n", GetLastError());
1673 result = CryptDestroyKey(hKey);
1674 ok(result, "%08x\n", GetLastError());
1676 /* Provoke errors */
1677 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1678 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1681 static void test_mac(void) {
1682 HCRYPTKEY hKey;
1683 HCRYPTHASH hHash;
1684 BOOL result;
1685 DWORD dwLen;
1686 BYTE abData[256], abEnc[264];
1687 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1688 int i;
1690 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1691 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1693 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1695 dwLen = 256;
1696 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1697 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1699 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1700 ok(result, "%08x\n", GetLastError());
1701 if (!result) return;
1703 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1704 ok(result, "%08x\n", GetLastError());
1706 dwLen = sizeof(abData)/sizeof(BYTE);
1707 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1708 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1710 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1712 result = CryptDestroyHash(hHash);
1713 ok(result, "%08x\n", GetLastError());
1715 result = CryptDestroyKey(hKey);
1716 ok(result, "%08x\n", GetLastError());
1718 /* Provoke errors */
1719 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1721 SetLastError(0xdeadbeef);
1722 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1723 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1724 broken(result), /* Win9x, WinMe, NT4, W2K */
1725 "%08x\n", GetLastError());
1727 result = CryptDestroyKey(hKey);
1728 ok(result, "%08x\n", GetLastError());
1731 static void test_import_private(void)
1733 DWORD dwLen, dwVal;
1734 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1735 BOOL result;
1736 static BYTE abSessionKey[148] = {
1737 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1738 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1739 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1740 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1741 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1742 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1743 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1744 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1745 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1746 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1747 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1748 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1749 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1750 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1751 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1752 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1753 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1754 0x04, 0x8c, 0x49, 0x92
1756 static BYTE abEncryptedMessage[12] = {
1757 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1758 0x1c, 0xfd, 0xde, 0x71
1760 BLOBHEADER *blobHeader = (BLOBHEADER *)abPlainPrivateKey;
1761 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(blobHeader+1);
1763 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1764 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1765 if (!result) {
1766 /* rsaenh compiled without OpenSSL */
1767 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1768 return;
1771 dwLen = (DWORD)sizeof(abSessionKey);
1772 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1773 ok(result, "%08x\n", GetLastError());
1774 if (!result) return;
1776 dwVal = 0xdeadbeef;
1777 dwLen = sizeof(DWORD);
1778 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1779 ok(result, "%08x\n", GetLastError());
1780 ok(dwVal ==
1781 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1782 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1783 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1784 " got %08x\n", dwVal);
1786 dwLen = (DWORD)sizeof(abEncryptedMessage);
1787 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1788 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1789 "%08x, len: %d\n", GetLastError(), dwLen);
1790 CryptDestroyKey(hSessionKey);
1792 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1794 dwLen = (DWORD)sizeof(abSessionKey);
1795 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1796 ok(result, "%08x\n", GetLastError());
1797 CryptDestroyKey(hSessionKey);
1798 if (!result) return;
1800 dwLen = (DWORD)sizeof(abSessionKey);
1801 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1802 ok(result, "%08x\n", GetLastError());
1803 if (!result) return;
1805 CryptDestroyKey(hSessionKey);
1806 CryptDestroyKey(hKeyExchangeKey);
1808 /* Test importing a private key with a buffer that's smaller than the
1809 * actual buffer. The private exponent can be omitted, its length is
1810 * inferred from the passed-in length parameter.
1812 dwLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
1813 rsaPubKey->bitlen / 8 + 5 * rsaPubKey->bitlen / 16;
1814 for (; dwLen < sizeof(abPlainPrivateKey); dwLen++)
1816 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1817 ok(result, "CryptImportKey failed at size %d: %d (%08x)\n", dwLen,
1818 GetLastError(), GetLastError());
1819 if (result)
1820 CryptDestroyKey(hKeyExchangeKey);
1824 static void test_verify_signature(void) {
1825 HCRYPTHASH hHash;
1826 HCRYPTKEY hPubSignKey;
1827 BYTE abData[] = "Wine rocks!";
1828 BOOL result;
1829 BYTE abPubKey[148] = {
1830 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1831 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1832 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1833 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1834 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1835 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1836 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1837 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1838 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1839 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1840 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1841 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1842 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1843 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1844 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1845 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1846 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1847 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1848 0xe1, 0x21, 0x50, 0xac
1850 /* md2 with hash oid */
1851 BYTE abSignatureMD2[128] = {
1852 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1853 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1854 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1855 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1856 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1857 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1858 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1859 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1860 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1861 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1862 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1863 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1864 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1865 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1866 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1867 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1869 /* md2 without hash oid */
1870 BYTE abSignatureMD2NoOID[128] = {
1871 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1872 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1873 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1874 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1875 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1876 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1877 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1878 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1879 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1880 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1881 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1882 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1883 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1884 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1885 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1886 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1888 /* md4 with hash oid */
1889 BYTE abSignatureMD4[128] = {
1890 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1891 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1892 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1893 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1894 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1895 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1896 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1897 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1898 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1899 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1900 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1901 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1902 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1903 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1904 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1905 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1907 /* md4 without hash oid */
1908 BYTE abSignatureMD4NoOID[128] = {
1909 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1910 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1911 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1912 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1913 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1914 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1915 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1916 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1917 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1918 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1919 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1920 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1921 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1922 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1923 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1924 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1926 /* md5 with hash oid */
1927 BYTE abSignatureMD5[128] = {
1928 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1929 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1930 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1931 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1932 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1933 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1934 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1935 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1936 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1937 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1938 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1939 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1940 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1941 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1942 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1943 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1945 /* md5 without hash oid */
1946 BYTE abSignatureMD5NoOID[128] = {
1947 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1948 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1949 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1950 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1951 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1952 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1953 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1954 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1955 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1956 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1957 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1958 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1959 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1960 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1961 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1962 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1964 /* sha with hash oid */
1965 BYTE abSignatureSHA[128] = {
1966 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1967 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1968 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1969 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1970 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1971 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1972 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1973 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1974 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1975 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1976 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1977 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1978 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1979 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1980 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1981 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1983 /* sha without hash oid */
1984 BYTE abSignatureSHANoOID[128] = {
1985 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1986 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1987 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1988 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1989 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1990 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1991 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1992 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1993 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1994 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1995 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1996 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1997 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1998 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1999 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
2000 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
2003 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
2004 ok(result, "%08x\n", GetLastError());
2005 if (!result) return;
2007 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
2008 ok(result, "%08x\n", GetLastError());
2009 if (!result) return;
2011 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2012 ok(result, "%08x\n", GetLastError());
2013 if (!result) return;
2015 /*check that a NULL pointer signature is correctly handled*/
2016 result = CryptVerifySignatureA(hHash, NULL, 128, hPubSignKey, NULL, 0);
2017 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
2018 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
2019 if (result) return;
2021 /* check that we get a bad signature error when the signature is too short*/
2022 SetLastError(0xdeadbeef);
2023 result = CryptVerifySignatureA(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
2024 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
2025 broken(result), /* Win9x, WinMe, NT4 */
2026 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2028 result = CryptVerifySignatureA(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
2029 ok(result, "%08x\n", GetLastError());
2030 if (!result) return;
2032 /* It seems that CPVerifySignature doesn't care about the OID at all. */
2033 result = CryptVerifySignatureA(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
2034 ok(result, "%08x\n", GetLastError());
2035 if (!result) return;
2037 result = CryptVerifySignatureA(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2038 ok(result, "%08x\n", GetLastError());
2039 if (!result) return;
2041 CryptDestroyHash(hHash);
2043 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
2044 ok(result, "%08x\n", GetLastError());
2045 if (!result) return;
2047 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2048 ok(result, "%08x\n", GetLastError());
2049 if (!result) return;
2051 result = CryptVerifySignatureA(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
2052 ok(result, "%08x\n", GetLastError());
2053 if (!result) return;
2055 result = CryptVerifySignatureA(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, 0);
2056 ok(result, "%08x\n", GetLastError());
2057 if (!result) return;
2059 result = CryptVerifySignatureA(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2060 ok(result, "%08x\n", GetLastError());
2061 if (!result) return;
2063 CryptDestroyHash(hHash);
2065 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
2066 ok(result, "%08x\n", GetLastError());
2067 if (!result) return;
2069 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2070 ok(result, "%08x\n", GetLastError());
2071 if (!result) return;
2073 result = CryptVerifySignatureA(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
2074 ok(result, "%08x\n", GetLastError());
2075 if (!result) return;
2077 result = CryptVerifySignatureA(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, 0);
2078 ok(result, "%08x\n", GetLastError());
2079 if (!result) return;
2081 result = CryptVerifySignatureA(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2082 ok(result, "%08x\n", GetLastError());
2083 if (!result) return;
2085 CryptDestroyHash(hHash);
2087 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
2088 ok(result, "%08x\n", GetLastError());
2089 if (!result) return;
2091 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2092 ok(result, "%08x\n", GetLastError());
2093 if (!result) return;
2095 result = CryptVerifySignatureA(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
2096 ok(result, "%08x\n", GetLastError());
2097 if (!result) return;
2099 result = CryptVerifySignatureA(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, 0);
2100 ok(result, "%08x\n", GetLastError());
2101 if (!result) return;
2103 result = CryptVerifySignatureA(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2104 ok(result, "%08x\n", GetLastError());
2105 if (!result) return;
2107 CryptDestroyHash(hHash);
2108 CryptDestroyKey(hPubSignKey);
2111 static void test_rsa_encrypt(void)
2113 HCRYPTKEY hRSAKey;
2114 BYTE abData[2048] = "Wine rocks!";
2115 BOOL result;
2116 DWORD dwVal, dwLen;
2118 /* It is allowed to use the key exchange key for encryption/decryption */
2119 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
2120 ok (result, "%08x\n", GetLastError());
2121 if (!result) return;
2123 dwLen = 12;
2124 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
2125 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
2126 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
2127 dwLen = 12;
2128 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
2129 ok (result, "%08x\n", GetLastError());
2130 if (!result) return;
2132 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
2133 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
2135 dwVal = 0xdeadbeef;
2136 dwLen = sizeof(DWORD);
2137 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2138 ok(result, "%08x\n", GetLastError());
2139 ok(dwVal ==
2140 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2141 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2142 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2143 " got %08x\n", dwVal);
2145 /* An RSA key doesn't support salt */
2146 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
2147 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
2148 "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
2150 /* The key exchange key's public key may be exported.. */
2151 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2152 ok(result, "%08x\n", GetLastError());
2153 /* but its private key may not be. */
2154 SetLastError(0xdeadbeef);
2155 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2156 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
2157 broken(result), /* Win9x/NT4 */
2158 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
2159 /* Setting the permissions of the key exchange key isn't allowed, either. */
2160 dwVal |= CRYPT_EXPORT;
2161 SetLastError(0xdeadbeef);
2162 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2163 ok(!result &&
2164 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
2165 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
2167 CryptDestroyKey(hRSAKey);
2169 /* It is not allowed to use the signature key for encryption/decryption */
2170 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
2171 ok (result, "%08x\n", GetLastError());
2172 if (!result) return;
2174 dwVal = 0xdeadbeef;
2175 dwLen = sizeof(DWORD);
2176 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2177 ok(result, "%08x\n", GetLastError());
2178 ok(dwVal ==
2179 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2180 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2181 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2182 " got %08x\n", dwVal);
2184 /* The signature key's public key may also be exported.. */
2185 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2186 ok(result, "%08x\n", GetLastError());
2187 /* but its private key may not be. */
2188 SetLastError(0xdeadbeef);
2189 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2190 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
2191 broken(result), /* Win9x/NT4 */
2192 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
2193 /* Setting the permissions of the signature key isn't allowed, either. */
2194 dwVal |= CRYPT_EXPORT;
2195 SetLastError(0xdeadbeef);
2196 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2197 ok(!result &&
2198 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
2199 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
2201 dwLen = 12;
2202 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
2203 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
2205 CryptDestroyKey(hRSAKey);
2208 static void test_import_export(void)
2210 DWORD dwLen, dwDataLen, dwVal;
2211 HCRYPTKEY hPublicKey, hPrivKey;
2212 BOOL result;
2213 ALG_ID algID;
2214 BYTE emptyKey[2048], *exported_key;
2215 static BYTE abPlainPublicKey[84] = {
2216 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
2217 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
2218 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
2219 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2220 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2221 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2222 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2223 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2224 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2225 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2226 0x11, 0x11, 0x11, 0x11
2228 static BYTE priv_key_with_high_bit[] = {
2229 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2230 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2231 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2232 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2233 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2234 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2235 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2236 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2237 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2238 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2239 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2240 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2241 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2242 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2243 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2244 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2245 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2246 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2247 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2248 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2249 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2250 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2251 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2252 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2253 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2254 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2255 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2256 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2257 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2258 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2259 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2260 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2261 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2262 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2263 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2264 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2265 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2266 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2267 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2268 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2269 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2270 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2271 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2272 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2273 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2274 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2275 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2276 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2277 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2278 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2279 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2280 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2281 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2282 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2283 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2284 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2285 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2286 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2287 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2288 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2289 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2290 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2291 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2292 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2293 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2294 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2295 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2296 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2297 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2298 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2299 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2300 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2301 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2302 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2303 0xb6, 0x5f, 0x01, 0x5e
2305 static const BYTE expected_exported_priv_key[] = {
2306 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2307 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2308 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2309 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2310 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2311 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2312 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2313 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2314 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2315 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2316 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2317 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2318 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2319 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2320 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2321 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2322 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2323 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2324 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2325 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2326 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2327 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2328 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2329 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2330 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2331 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2332 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2333 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2334 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2335 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2336 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2337 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2338 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2339 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2340 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2341 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2342 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2343 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2344 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2345 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2346 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2347 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2348 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2349 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2350 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2351 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2352 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2353 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2354 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2355 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2356 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2357 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2358 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2359 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2360 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2361 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2362 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2363 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2364 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2365 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2366 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2367 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2368 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2369 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2370 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2371 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2372 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2373 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2374 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2375 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2376 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2377 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2378 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2379 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2380 0xb6, 0x5f, 0x01, 0x5e
2383 dwLen=84;
2384 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2385 ok(result, "failed to import the public key\n");
2387 dwDataLen=sizeof(algID);
2388 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2389 ok(result, "failed to get the KP_ALGID from the imported public key\n");
2390 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2392 dwVal = 0xdeadbeef;
2393 dwDataLen = sizeof(DWORD);
2394 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2395 ok(result, "%08x\n", GetLastError());
2396 ok(dwVal ==
2397 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2398 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2399 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2400 " got %08x\n", dwVal);
2401 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2402 ok(result, "failed to export the fresh imported public key\n");
2403 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2404 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2406 CryptDestroyKey(hPublicKey);
2408 result = CryptImportKey(hProv, priv_key_with_high_bit,
2409 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2410 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2412 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2413 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2414 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2415 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2416 &dwDataLen);
2417 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2419 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2420 dwDataLen);
2421 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2422 "unexpected value\n");
2424 HeapFree(GetProcessHeap(), 0, exported_key);
2426 CryptDestroyKey(hPrivKey);
2429 static void test_import_hmac(void)
2431 /* Test cases from RFC 2202, section 3 */
2432 static const struct rfc2202_test_case {
2433 const char *key;
2434 DWORD key_len;
2435 const char *data;
2436 const DWORD data_len;
2437 const char *digest;
2438 } cases[] = {
2439 { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2440 "\x0b\x0b\x0b\x0b", 20,
2441 "Hi There", 8,
2442 "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2443 "\xf1\x46\xbe\x00" },
2444 { "Jefe", 4,
2445 "what do ya want for nothing?", 28,
2446 "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2447 "\x25\x9a\x7c\x79" },
2448 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2449 "\xaa\xaa\xaa\xaa", 20,
2450 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2451 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2452 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2453 "\xdd\xdd", 50,
2454 "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2455 "\x63\xf1\x75\xd3" },
2456 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2457 "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2458 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2459 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2460 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2461 "\xcd\xcd", 50,
2462 "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2463 "\x2d\x72\x35\xda" },
2464 { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2465 "\x0c\x0c\x0c\x0c", 20,
2466 "Test With Truncation", 20,
2467 "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2468 "\x4a\x9a\x5a\x04" },
2469 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2470 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2471 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2472 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2473 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2475 "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2476 "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2477 "\xed\x40\x21\x12" },
2478 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2479 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2480 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2481 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2482 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2484 "Test Using Larger Than Block-Size Key and Larger "
2485 "Than One Block-Size Data", 73,
2486 "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2487 "\xbb\xff\x1a\x91" }
2489 DWORD i;
2491 for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++)
2493 const struct rfc2202_test_case *test_case = &cases[i];
2494 DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2495 BYTE *blob = HeapAlloc(GetProcessHeap(), 0, size);
2497 if (blob)
2499 BLOBHEADER *header = (BLOBHEADER *)blob;
2500 DWORD *key_len = (DWORD *)(header + 1);
2501 BYTE *key_bytes = (BYTE *)(key_len + 1);
2502 BOOL result;
2503 HCRYPTKEY key;
2505 header->bType = PLAINTEXTKEYBLOB;
2506 header->bVersion = CUR_BLOB_VERSION;
2507 header->reserved = 0;
2508 header->aiKeyAlg = CALG_RC2;
2509 *key_len = test_case->key_len;
2510 memcpy(key_bytes, test_case->key, *key_len);
2511 result = CryptImportKey(hProv, blob, size, 0, CRYPT_IPSEC_HMAC_KEY, &key);
2512 ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
2513 if (result)
2515 HCRYPTHASH hash;
2516 HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2517 BYTE digest[20];
2518 DWORD digest_size;
2520 result = CryptCreateHash(hProv, CALG_HMAC, key, 0, &hash);
2521 ok(result, "CryptCreateHash failed on test case %d: %08x\n", i, GetLastError());
2522 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2523 ok(result, "CryptSetHashParam failed on test case %d: %08x\n", i, GetLastError());
2524 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2525 ok(result, "CryptHashData failed on test case %d: %08x\n", i, GetLastError());
2526 digest_size = sizeof(digest);
2527 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2528 ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
2529 ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected value on test case %d\n", i);
2530 CryptDestroyHash(hash);
2531 CryptDestroyKey(key);
2533 HeapFree(GetProcessHeap(), 0, blob);
2538 static void test_schannel_provider(void)
2540 HCRYPTPROV hProv;
2541 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2542 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2543 BOOL result;
2544 DWORD dwLen;
2545 SCHANNEL_ALG saSChannelAlg;
2546 CRYPT_DATA_BLOB data_blob;
2547 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2548 BYTE abTLS1Master[140] = {
2549 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2550 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2551 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2552 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2553 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2554 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2555 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2556 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2557 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2558 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2559 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2560 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2561 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2562 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2563 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2564 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2565 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2566 0xd3, 0x1e, 0x82, 0xb3
2568 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2569 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2570 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2571 BYTE abClientFinished[16] = "client finished";
2572 BYTE abData[16] = "Wine rocks!";
2573 BYTE abMD5Hash[16];
2574 static const BYTE abEncryptedData[16] = {
2575 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2576 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2578 static const BYTE abPRF[16] = {
2579 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2580 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2582 static const BYTE abMD5[16] = {
2583 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2584 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2587 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2588 if (!result)
2590 win_skip("no PROV_RSA_SCHANNEL support\n");
2591 return;
2593 ok (result, "%08x\n", GetLastError());
2594 if (result)
2595 CryptReleaseContext(hProv, 0);
2597 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2598 ok (result, "%08x\n", GetLastError());
2599 if (!result) return;
2601 /* To get deterministic results, we import the TLS1 master secret (which
2602 * is typically generated from a random generator). Therefore, we need
2603 * an RSA key. */
2604 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2605 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2606 ok (result, "%08x\n", GetLastError());
2607 if (!result) return;
2609 dwLen = (DWORD)sizeof(abTLS1Master);
2610 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2611 ok (result, "%08x\n", GetLastError());
2612 if (!result) return;
2614 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2615 * (Keys can only be derived from hashes, not from other keys.)
2616 * The hash can't be created yet because the key doesn't have the client
2617 * random or server random set.
2619 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2620 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER,
2621 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2623 /* Setting the TLS1 client and server random parameters, as well as the
2624 * MAC and encryption algorithm parameters. */
2625 data_blob.cbData = 33;
2626 data_blob.pbData = abClientSecret;
2627 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2628 ok (result, "%08x\n", GetLastError());
2629 if (!result) return;
2631 data_blob.cbData = 33;
2632 data_blob.pbData = abServerSecret;
2633 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2634 ok (result, "%08x\n", GetLastError());
2635 if (!result) return;
2637 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2638 ok (result, "%08x\n", GetLastError());
2639 if (!result) return;
2641 /* Deriving the server write encryption key from the master hash can't
2642 * succeed before the encryption key algorithm is set.
2644 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2645 ok (!result && GetLastError() == NTE_BAD_FLAGS,
2646 "expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2648 CryptDestroyHash(hMasterHash);
2650 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2651 saSChannelAlg.Algid = CALG_DES;
2652 saSChannelAlg.cBits = 64;
2653 saSChannelAlg.dwFlags = 0;
2654 saSChannelAlg.dwReserved = 0;
2655 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2656 ok (result, "%08x\n", GetLastError());
2657 if (!result) return;
2659 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2660 saSChannelAlg.Algid = CALG_MD5;
2661 saSChannelAlg.cBits = 128;
2662 saSChannelAlg.dwFlags = 0;
2663 saSChannelAlg.dwReserved = 0;
2664 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2665 ok (result, "%08x\n", GetLastError());
2666 if (!result) return;
2668 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2669 ok (result, "%08x\n", GetLastError());
2670 if (!result) return;
2672 /* Deriving the server write encryption key from the master hash */
2673 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2674 ok (result, "%08x\n", GetLastError());
2675 if (!result) return;
2677 /* Encrypting some data with the server write encryption key and checking the result. */
2678 dwLen = 12;
2679 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2680 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2682 /* Second test case: Test the TLS1 pseudo random number function. */
2683 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2684 ok (result, "%08x\n", GetLastError());
2685 if (!result) return;
2687 /* Set the label and seed parameters for the random number function */
2688 data_blob.cbData = 36;
2689 data_blob.pbData = abHashedHandshakes;
2690 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2691 ok (result, "%08x\n", GetLastError());
2692 if (!result) return;
2694 data_blob.cbData = 15;
2695 data_blob.pbData = abClientFinished;
2696 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2697 ok (result, "%08x\n", GetLastError());
2698 if (!result) return;
2700 /* Generate some pseudo random bytes and check if they are correct. */
2701 dwLen = (DWORD)sizeof(abData);
2702 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2703 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2704 "%08x\n", GetLastError());
2706 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2707 * Hash some data with the HMAC. Compare results. */
2708 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2709 ok (result, "%08x\n", GetLastError());
2710 if (!result) return;
2712 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2713 ok (result, "%08x\n", GetLastError());
2714 if (!result) return;
2716 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2717 ok (result, "%08x\n", GetLastError());
2718 if (!result) return;
2720 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2721 ok (result, "%08x\n", GetLastError());
2722 if (!result) return;
2724 dwLen = (DWORD)sizeof(abMD5Hash);
2725 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2726 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2728 CryptDestroyHash(hHMAC);
2729 CryptDestroyHash(hTLS1PRF);
2730 CryptDestroyHash(hMasterHash);
2731 CryptDestroyKey(hServerWriteMACKey);
2732 CryptDestroyKey(hServerWriteKey);
2733 CryptDestroyKey(hRSAKey);
2734 CryptDestroyKey(hMasterSecret);
2735 CryptReleaseContext(hProv, 0);
2736 CryptAcquireContextA(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2739 /* Test that a key can be used to encrypt data and exported, and that, when
2740 * the exported key is imported again, can be used to decrypt the original
2741 * data again.
2743 static void test_rsa_round_trip(void)
2745 static const char test_string[] = "Well this is a fine how-do-you-do.";
2746 HCRYPTPROV prov;
2747 HCRYPTKEY signKey, keyExchangeKey;
2748 BOOL result;
2749 BYTE data[256], *exportedKey;
2750 DWORD dataLen, keyLen;
2752 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2753 CRYPT_DELETEKEYSET);
2755 /* Generate a new key... */
2756 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2757 CRYPT_NEWKEYSET);
2758 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
2759 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2760 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2761 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2762 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2763 /* encrypt some data with it... */
2764 memcpy(data, test_string, strlen(test_string) + 1);
2765 dataLen = strlen(test_string) + 1;
2766 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2767 sizeof(data));
2768 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2769 broken(GetLastError() == NTE_PERM /* NT4 */),
2770 "CryptEncrypt failed: %08x\n", GetLastError());
2771 /* export the key... */
2772 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2773 &keyLen);
2774 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2775 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2776 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2777 &keyLen);
2778 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2779 /* destroy the key... */
2780 CryptDestroyKey(keyExchangeKey);
2781 CryptDestroyKey(signKey);
2782 /* import the key again... */
2783 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2784 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2785 HeapFree(GetProcessHeap(), 0, exportedKey);
2786 /* and decrypt the data encrypted with the original key with the imported
2787 * key.
2789 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2790 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2791 broken(GetLastError() == NTE_PERM /* NT4 */),
2792 "CryptDecrypt failed: %08x\n", GetLastError());
2793 if (result)
2795 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2796 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2798 CryptDestroyKey(keyExchangeKey);
2799 CryptReleaseContext(prov, 0);
2801 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2802 CRYPT_DELETEKEYSET);
2805 static void test_enum_container(void)
2807 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2808 DWORD dwBufferLen;
2809 BOOL result, fFound = FALSE;
2811 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2812 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2813 SetLastError(0xdeadbeef);
2814 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2815 ok (result, "%08x\n", GetLastError());
2816 ok (dwBufferLen == MAX_PATH + 1 ||
2817 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2818 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2820 /* If the result fits into abContainerName dwBufferLen is left untouched */
2821 dwBufferLen = (DWORD)sizeof(abContainerName);
2822 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2823 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2825 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2826 do {
2827 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2828 dwBufferLen = (DWORD)sizeof(abContainerName);
2829 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2831 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2834 static BYTE signBlob[] = {
2835 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2836 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2837 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2838 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2839 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2840 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2841 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2842 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2843 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2844 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2845 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2846 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2847 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2848 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2849 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2850 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2851 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2852 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2853 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2854 0xb6,0x85,0x86,0x07 };
2856 static void test_null_provider(void)
2858 HCRYPTPROV prov;
2859 HCRYPTKEY key;
2860 BOOL result;
2861 DWORD keySpec, dataLen,dwParam;
2862 char szName[MAX_PATH];
2864 result = CryptAcquireContextA(NULL, szContainer, NULL, 0, 0);
2865 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2866 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2867 result = CryptAcquireContextA(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2868 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2869 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2870 result = CryptAcquireContextA(NULL, szContainer, NULL, PROV_RSA_FULL,
2871 CRYPT_DELETEKEYSET);
2872 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2873 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2874 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2875 CRYPT_DELETEKEYSET);
2876 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2877 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2878 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2879 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2880 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2882 /* Delete the default container. */
2883 CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2884 /* Once you've deleted the default container you can't open it as if it
2885 * already exists.
2887 result = CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2888 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2889 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2890 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2891 result = CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL,
2892 CRYPT_VERIFYCONTEXT);
2893 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
2894 if (!result) return;
2895 dataLen = sizeof(keySpec);
2896 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2897 if (result)
2898 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2899 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2900 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2901 * supported, you can't get the keys from this container.
2903 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2904 ok(!result && GetLastError() == NTE_NO_KEY,
2905 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2906 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2907 ok(!result && GetLastError() == NTE_NO_KEY,
2908 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2909 result = CryptReleaseContext(prov, 0);
2910 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2911 /* You can create a new default container. */
2912 result = CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL,
2913 CRYPT_NEWKEYSET);
2914 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
2915 /* But you still can't get the keys (until one's been generated.) */
2916 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2917 ok(!result && GetLastError() == NTE_NO_KEY,
2918 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2919 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2920 ok(!result && GetLastError() == NTE_NO_KEY,
2921 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2922 CryptReleaseContext(prov, 0);
2923 CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2925 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2926 CRYPT_DELETEKEYSET);
2927 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2928 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2929 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2930 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2931 CRYPT_VERIFYCONTEXT);
2932 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2933 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2934 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2935 CRYPT_NEWKEYSET);
2936 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
2937 if (!result) return;
2938 /* Test provider parameters getter */
2939 dataLen = sizeof(dwParam);
2940 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2941 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2942 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2943 dataLen = sizeof(dwParam);
2944 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2945 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2946 "Expected 0, got 0x%08X\n",dwParam);
2947 dataLen = sizeof(dwParam);
2948 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2949 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2950 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2951 dataLen = sizeof(keySpec);
2952 SetLastError(0xdeadbeef);
2953 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2954 if (!result && GetLastError() == NTE_BAD_TYPE)
2955 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2956 else
2957 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2958 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2959 /* PP_CONTAINER parameter */
2960 dataLen = sizeof(szName);
2961 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2962 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2963 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2964 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2965 /* PP_UNIQUE_CONTAINER parameter */
2966 dataLen = sizeof(szName);
2967 SetLastError(0xdeadbeef);
2968 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2969 if (!result && GetLastError() == NTE_BAD_TYPE)
2971 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2973 else
2975 char container[MAX_PATH];
2977 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2978 uniquecontainer(container);
2979 todo_wine
2981 ok(dataLen == strlen(container)+1 ||
2982 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2983 "Expected a param length of 70, got %d\n", dataLen);
2984 ok(!strcmp(container, szName) ||
2985 broken(!strcmp(szName, szContainer)) /* WinME */,
2986 "Wrong container name : %s\n", szName);
2989 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2990 ok(!result && GetLastError() == NTE_NO_KEY,
2991 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2992 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2993 ok(!result && GetLastError() == NTE_NO_KEY,
2994 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2996 /* Importing a key exchange blob.. */
2997 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2998 0, 0, &key);
2999 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3000 CryptDestroyKey(key);
3001 /* allows access to the key exchange key.. */
3002 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3003 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3004 CryptDestroyKey(key);
3005 /* but not to the private key. */
3006 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3007 ok(!result && GetLastError() == NTE_NO_KEY,
3008 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3009 CryptReleaseContext(prov, 0);
3010 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3011 CRYPT_DELETEKEYSET);
3013 /* Whereas importing a sign blob.. */
3014 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3015 CRYPT_NEWKEYSET);
3016 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3017 if (!result) return;
3018 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
3019 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3020 CryptDestroyKey(key);
3021 /* doesn't allow access to the key exchange key.. */
3022 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3023 ok(!result && GetLastError() == NTE_NO_KEY,
3024 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3025 /* but does to the private key. */
3026 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3027 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3028 CryptDestroyKey(key);
3029 CryptReleaseContext(prov, 0);
3031 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3032 CRYPT_DELETEKEYSET);
3034 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
3035 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3036 CRYPT_NEWKEYSET);
3037 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3038 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
3039 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
3040 CryptDestroyKey(key);
3041 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3042 ok(!result, "expected CryptGetUserKey to fail\n");
3043 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3044 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
3045 CryptDestroyKey(key);
3046 CryptReleaseContext(prov, 0);
3048 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3049 CRYPT_DELETEKEYSET);
3051 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
3052 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3053 CRYPT_NEWKEYSET);
3054 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3055 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
3056 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
3057 CryptDestroyKey(key);
3058 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3059 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
3060 CryptDestroyKey(key);
3061 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3062 ok(!result, "expected CryptGetUserKey to fail\n");
3063 CryptReleaseContext(prov, 0);
3065 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3066 CRYPT_DELETEKEYSET);
3068 /* test for the bug in accessing the user key in a container
3070 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3071 CRYPT_NEWKEYSET);
3072 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3073 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
3074 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
3075 CryptDestroyKey(key);
3076 CryptReleaseContext(prov,0);
3077 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,0);
3078 ok(result, "CryptAcquireContextA failed: 0x%08x\n", GetLastError());
3079 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3080 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
3081 CryptDestroyKey(key);
3082 CryptReleaseContext(prov, 0);
3084 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3085 CRYPT_DELETEKEYSET);
3087 /* test the machine key set */
3088 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3089 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
3090 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3091 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
3092 ok(result, "CryptAcquireContextA with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
3093 CryptReleaseContext(prov, 0);
3094 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3095 CRYPT_MACHINE_KEYSET);
3096 ok(result, "CryptAcquireContextA with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
3097 CryptReleaseContext(prov,0);
3098 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3099 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
3100 ok(result, "CryptAcquireContextA with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
3101 GetLastError());
3102 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3103 CRYPT_MACHINE_KEYSET);
3104 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
3105 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3109 static void test_key_permissions(void)
3111 HCRYPTKEY hKey1, hKey2;
3112 DWORD dwVal, dwLen;
3113 BOOL result;
3115 /* Create keys that are exportable */
3116 if (!init_base_environment(CRYPT_EXPORTABLE))
3117 return;
3119 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
3120 ok (result, "%08x\n", GetLastError());
3121 if (!result) return;
3123 dwVal = 0xdeadbeef;
3124 dwLen = sizeof(DWORD);
3125 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3126 ok(result, "%08x\n", GetLastError());
3127 ok(dwVal ==
3128 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
3129 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3130 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3131 " got %08x\n", dwVal);
3133 /* The key exchange key's public key may be exported.. */
3134 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
3135 ok(result, "%08x\n", GetLastError());
3136 /* and its private key may be too. */
3137 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
3138 ok(result, "%08x\n", GetLastError());
3139 /* Turning off the key's export permissions is "allowed".. */
3140 dwVal &= ~CRYPT_EXPORT;
3141 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
3142 ok(result ||
3143 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
3144 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
3145 "%08x\n", GetLastError());
3146 /* but it has no effect. */
3147 dwVal = 0xdeadbeef;
3148 dwLen = sizeof(DWORD);
3149 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3150 ok(result, "%08x\n", GetLastError());
3151 ok(dwVal ==
3152 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
3153 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3154 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3155 " got %08x\n", dwVal);
3156 /* Thus, changing the export flag of the key doesn't affect whether the key
3157 * may be exported.
3159 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
3160 ok(result, "%08x\n", GetLastError());
3162 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
3163 ok (result, "%08x\n", GetLastError());
3165 /* A subsequent get of the same key, into a different handle, also doesn't
3166 * show that the permissions have been changed.
3168 dwVal = 0xdeadbeef;
3169 dwLen = sizeof(DWORD);
3170 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3171 ok(result, "%08x\n", GetLastError());
3172 ok(dwVal ==
3173 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
3174 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3175 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3176 " got %08x\n", dwVal);
3178 CryptDestroyKey(hKey2);
3179 CryptDestroyKey(hKey1);
3181 clean_up_base_environment();
3184 static void test_key_initialization(void)
3186 DWORD dwLen;
3187 HCRYPTPROV prov1, prov2;
3188 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
3189 BOOL result;
3190 static BYTE abSessionKey[148] = {
3191 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
3192 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
3193 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
3194 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
3195 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
3196 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
3197 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
3198 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
3199 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
3200 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
3201 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
3202 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
3203 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
3204 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
3205 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
3206 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
3207 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
3208 0x04, 0x8c, 0x49, 0x92
3211 /* Like init_base_environment, but doesn't generate new keys, as they'll
3212 * be imported instead.
3214 if (!CryptAcquireContextA(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
3216 result = CryptAcquireContextA(&prov1, szContainer, szProvider, PROV_RSA_FULL,
3217 CRYPT_NEWKEYSET);
3218 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3220 dwLen = (DWORD)sizeof(abPlainPrivateKey);
3221 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
3222 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3224 dwLen = (DWORD)sizeof(abSessionKey);
3225 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
3226 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3228 /* Once the key has been imported, subsequently acquiring a context with
3229 * the same name will allow retrieving the key.
3231 result = CryptAcquireContextA(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
3232 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3233 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
3234 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3235 if (result) CryptDestroyKey(hKey);
3236 CryptReleaseContext(prov2, 0);
3238 CryptDestroyKey(hSessionKey);
3239 CryptDestroyKey(hKeyExchangeKey);
3240 CryptReleaseContext(prov1, 0);
3241 CryptAcquireContextA(&prov1, szContainer, NULL, PROV_RSA_FULL,
3242 CRYPT_DELETEKEYSET);
3245 START_TEST(rsaenh)
3247 if (!init_base_environment(0))
3248 return;
3249 test_prov();
3250 test_gen_random();
3251 test_hashes();
3252 test_rc4();
3253 test_rc2();
3254 test_des();
3255 test_3des112();
3256 test_3des();
3257 test_hmac();
3258 test_mac();
3259 test_block_cipher_modes();
3260 test_import_private();
3261 test_verify_signature();
3262 test_rsa_encrypt();
3263 test_import_export();
3264 test_import_hmac();
3265 test_enum_container();
3266 clean_up_base_environment();
3267 test_key_permissions();
3268 test_key_initialization();
3269 test_schannel_provider();
3270 test_null_provider();
3271 test_rsa_round_trip();
3272 if (!init_aes_environment())
3273 return;
3274 test_aes(128);
3275 test_aes(192);
3276 test_aes(256);
3277 test_sha2();
3278 clean_up_aes_environment();