rsaenh/tests: Add a pre XP DES compatibility test.
[wine.git] / dlls / rsaenh / tests / rsaenh.c
blob467551e43d002533256b8052e89b6c865329ddaa
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;
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 result = CryptHashData(hHash, pbData, sizeof(pbData), CRYPT_USERDATA);
453 if (!result && GetLastError() == NTE_BAD_FLAGS) /* <= NT4 */
455 ok(broken(1), "Failed to support CRYPT_USERDATA flag\n");
456 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
458 ok(result, "%08x\n", GetLastError());
460 len = sizeof(DWORD);
461 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
462 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
464 len = 16;
465 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
466 ok(result, "%08x\n", GetLastError());
468 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
470 result = CryptDestroyHash(hHash);
471 ok(result, "%08x\n", GetLastError());
473 /* MD5 Hashing */
474 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
475 ok(result, "%08x\n", GetLastError());
477 len = sizeof(DWORD);
478 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
479 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
481 result = CryptHashData(hHash, pbData, sizeof(pbData), ~0);
482 ok(!result && GetLastError() == NTE_BAD_FLAGS, "%08x\n", GetLastError());
484 result = CryptHashData(hHash, pbData, sizeof(pbData), CRYPT_USERDATA);
485 if (!result && GetLastError() == NTE_BAD_FLAGS) /* <= NT4 */
487 ok(broken(1), "Failed to support CRYPT_USERDATA flag\n");
488 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
490 ok(result, "%08x\n", GetLastError());
492 len = 16;
493 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
494 ok(result, "%08x\n", GetLastError());
496 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
498 result = CryptDestroyHash(hHash);
499 ok(result, "%08x\n", GetLastError());
501 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
502 ok(result, "%08x\n", GetLastError());
504 /* The hash is available even if CryptHashData hasn't been called */
505 len = 16;
506 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
507 ok(result, "%08x\n", GetLastError());
509 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
511 /* It's also stable: getting it twice results in the same value */
512 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
513 ok(result, "%08x\n", GetLastError());
515 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
517 /* Can't add data after the hash been retrieved */
518 SetLastError(0xdeadbeef);
519 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
520 ok(!result, "Expected failure\n");
521 ok(GetLastError() == NTE_BAD_HASH_STATE ||
522 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
523 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
525 /* You can still retrieve the hash, its value just hasn't changed */
526 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
527 ok(result, "%08x\n", GetLastError());
529 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
531 result = CryptDestroyHash(hHash);
532 ok(result, "%08x\n", GetLastError());
534 /* SHA1 Hashing */
535 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
536 ok(result, "%08x\n", GetLastError());
538 result = CryptHashData(hHash, pbData, 5, CRYPT_USERDATA);
539 if (!result && GetLastError() == NTE_BAD_FLAGS) /* <= NT4 */
541 ok(broken(1), "Failed to support CRYPT_USERDATA flag\n");
542 result = CryptHashData(hHash, pbData, 5, 0);
544 ok(result, "%08x\n", GetLastError());
546 if(pCryptDuplicateHash) {
547 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
548 ok(result, "%08x\n", GetLastError());
550 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
551 ok(result, "%08x\n", GetLastError());
553 len = sizeof(DWORD);
554 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
555 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
557 len = 20;
558 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
559 ok(result, "%08x\n", GetLastError());
561 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
563 result = CryptDestroyHash(hHashClone);
564 ok(result, "%08x\n", GetLastError());
567 result = CryptDestroyHash(hHash);
568 ok(result, "%08x\n", GetLastError());
570 /* The SHA-2 variants aren't supported in the RSA full provider */
571 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
572 ok(!result && GetLastError() == NTE_BAD_ALGID,
573 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
574 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
575 ok(!result && GetLastError() == NTE_BAD_ALGID,
576 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
577 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
578 ok(!result && GetLastError() == NTE_BAD_ALGID,
579 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
581 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
582 ok(result, "CryptAcquireContextA failed 0x%08x\n", GetLastError());
584 result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash);
585 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
587 /* release provider before using the hash */
588 result = CryptReleaseContext(prov, 0);
589 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
591 SetLastError(0xdeadbeef);
592 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
593 error = GetLastError();
594 ok(!result, "CryptHashData succeeded\n");
595 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
597 SetLastError(0xdeadbeef);
598 result = CryptDestroyHash(hHash);
599 error = GetLastError();
600 ok(!result, "CryptDestroyHash succeeded\n");
601 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
603 if (!pCryptDuplicateHash)
605 win_skip("CryptDuplicateHash is not available\n");
606 return;
609 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
610 ok(result, "CryptAcquireContextA failed 0x%08x\n", GetLastError());
612 result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
613 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
615 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
616 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
618 result = pCryptDuplicateHash(hHash, NULL, 0, &hHashClone);
619 ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
621 len = 20;
622 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
623 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
625 /* add data after duplicating the hash */
626 result = CryptHashData(hHash, (const BYTE *)"more data", sizeof("more data"), 0);
627 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
629 result = CryptDestroyHash(hHash);
630 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
632 result = CryptDestroyHash(hHashClone);
633 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
635 result = CryptReleaseContext(prov, 0);
636 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
638 /* Test CALG_SSL3_SHAMD5 */
639 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
640 ok(result, "CryptAcquireContextA failed 0x%08x\n", GetLastError());
642 /* Step 1: create an MD5 hash of the data */
643 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
644 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
645 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
646 ok(result, "%08x\n", GetLastError());
647 len = 16;
648 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
649 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
650 result = CryptDestroyHash(hHash);
651 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
652 /* Step 2: create a SHA1 hash of the data */
653 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
654 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
655 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
656 ok(result, "%08x\n", GetLastError());
657 len = 20;
658 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue + 16, &len, 0);
659 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
660 result = CryptDestroyHash(hHash);
661 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
662 /* Step 3: create a CALG_SSL3_SHAMD5 hash handle */
663 result = CryptCreateHash(hProv, CALG_SSL3_SHAMD5, 0, 0, &hHash);
664 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
665 /* Test that CryptHashData fails on this hash */
666 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
667 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
668 result = CryptSetHashParam(hHash, HP_HASHVAL, pbHashValue, 0);
669 ok(result, "%08x\n", GetLastError());
670 len = (DWORD)sizeof(abPlainPrivateKey);
671 result = CryptImportKey(hProv, abPlainPrivateKey, len, 0, 0, &hKeyExchangeKey);
672 ok(result, "%08x\n", GetLastError());
673 len = 0;
674 result = CryptSignHashA(hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &len);
675 ok(result, "%08x\n", GetLastError());
676 ok(len == 128, "expected len 128, got %d\n", len);
677 result = CryptSignHashA(hHash, AT_KEYEXCHANGE, NULL, 0, pbSigValue, &len);
678 ok(result, "%08x\n", GetLastError());
679 ok(!memcmp(pbSigValue, signed_ssl3_shamd5_hash, len), "unexpected value\n");
680 if (len != 128 || memcmp(pbSigValue, signed_ssl3_shamd5_hash, len))
682 printBytes("expected", signed_ssl3_shamd5_hash,
683 sizeof(signed_ssl3_shamd5_hash));
684 printBytes("got", pbSigValue, len);
686 result = CryptDestroyKey(hKeyExchangeKey);
687 ok(result, "CryptDestroyKey failed 0x%08x\n", GetLastError());
688 result = CryptDestroyHash(hHash);
689 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
690 result = CryptReleaseContext(prov, 0);
691 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
694 static void test_block_cipher_modes(void)
696 static const BYTE plain[23] = {
697 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
698 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
699 static const BYTE ecb[24] = {
700 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
701 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
702 static const BYTE cbc[24] = {
703 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
704 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
705 static const BYTE cfb[24] = {
706 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
707 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
708 HCRYPTKEY hKey;
709 BOOL result;
710 BYTE abData[24];
711 DWORD dwMode, dwLen;
713 result = derive_key(CALG_RC2, &hKey, 40);
714 if (!result) return;
716 memcpy(abData, plain, sizeof(plain));
718 /* test default chaining mode */
719 dwMode = 0xdeadbeef;
720 dwLen = sizeof(dwMode);
721 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
722 ok(result, "%08x\n", GetLastError());
723 ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining mode\n");
725 dwMode = CRYPT_MODE_ECB;
726 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
727 ok(result, "%08x\n", GetLastError());
729 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
730 ok(result, "%08x\n", GetLastError());
731 ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
733 dwLen = 23;
734 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
735 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
736 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
738 SetLastError(ERROR_SUCCESS);
739 dwLen = 23;
740 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
741 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
742 "%08x, dwLen: %d\n", GetLastError(), dwLen);
744 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
745 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
746 "%08x, dwLen: %d\n", GetLastError(), dwLen);
748 dwMode = CRYPT_MODE_CBC;
749 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
750 ok(result, "%08x\n", GetLastError());
752 dwLen = 23;
753 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
754 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
755 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
757 dwLen = 23;
758 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
759 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
760 "%08x, dwLen: %d\n", GetLastError(), dwLen);
762 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
763 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
764 "%08x, dwLen: %d\n", GetLastError(), dwLen);
766 dwMode = CRYPT_MODE_CFB;
767 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
768 ok(result, "%08x\n", GetLastError());
770 dwLen = 16;
771 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
772 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
774 dwLen = 7;
775 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
776 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
777 "%08x, dwLen: %d\n", GetLastError(), dwLen);
779 dwLen = 8;
780 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
781 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
783 dwLen = 16;
784 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
785 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
786 "%08x, dwLen: %d\n", GetLastError(), dwLen);
788 dwMode = CRYPT_MODE_OFB;
789 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
790 ok(result, "%08x\n", GetLastError());
792 dwLen = 23;
793 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
794 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
796 CryptDestroyKey(hKey);
799 static void test_3des112(void)
801 HCRYPTKEY hKey;
802 BOOL result;
803 DWORD dwLen;
804 unsigned char pbData[16], enc_data[16], bad_data[16];
805 static const BYTE des112[16] = {
806 0x8e, 0x0c, 0x3c, 0xa3, 0x05, 0x88, 0x5f, 0x7a,
807 0x32, 0xa1, 0x06, 0x52, 0x64, 0xd2, 0x44, 0x1c };
808 int i;
810 result = derive_key(CALG_3DES_112, &hKey, 0);
811 if (!result) {
812 /* rsaenh compiled without OpenSSL */
813 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
814 return;
817 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
819 dwLen = 13;
820 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
821 ok(result, "%08x\n", GetLastError());
823 ok(!memcmp(pbData, des112, sizeof(des112)), "3DES_112 encryption failed!\n");
825 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
826 ok(result, "%08x\n", GetLastError());
828 for (i=0; i<4; i++)
830 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
832 dwLen = cTestData[i].enclen;
833 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
834 ok(result, "%08x\n", GetLastError());
835 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
836 memcpy(enc_data, pbData, cTestData[i].buflen);
838 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
839 ok(result, "%08x\n", GetLastError());
840 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
841 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
842 if((dwLen != cTestData[i].enclen) ||
843 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
845 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
846 printBytes("got",pbData,dwLen);
849 /* Test bad data:
850 Decrypting a block of bad data with Final = TRUE should restore the
851 initial state of the key as well as decrypting a block of good data.
854 /* Changing key state by setting Final = FALSE */
855 dwLen = cTestData[i].buflen;
856 memcpy(pbData, enc_data, cTestData[i].buflen);
857 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
858 ok(result, "%08x\n", GetLastError());
860 /* Restoring key state by decrypting bad_data with Final = TRUE */
861 memcpy(bad_data, enc_data, cTestData[i].buflen);
862 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
863 SetLastError(0xdeadbeef);
864 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
865 ok(!result, "CryptDecrypt should failed!\n");
866 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
867 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
868 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
870 /* Checking key state */
871 dwLen = cTestData[i].buflen;
872 memcpy(pbData, enc_data, cTestData[i].buflen);
873 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
874 ok(result, "%08x\n", GetLastError());
875 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
876 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
877 if((dwLen != cTestData[i].enclen) ||
878 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
880 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
881 printBytes("got",pbData,dwLen);
884 result = CryptDestroyKey(hKey);
885 ok(result, "%08x\n", GetLastError());
888 static void test_des(void)
890 HCRYPTKEY hKey;
891 BOOL result;
892 DWORD dwLen, dwMode;
893 unsigned char pbData[16], enc_data[16], bad_data[16];
894 static const BYTE des[16] = {
895 0x58, 0x86, 0x42, 0x46, 0x65, 0x4b, 0x92, 0x62,
896 0xcf, 0x0f, 0x65, 0x37, 0x43, 0x7a, 0x82, 0xb9 };
897 static const BYTE des_old_behavior[16] = {
898 0xb0, 0xfd, 0x11, 0x69, 0x76, 0xb1, 0xa1, 0x03,
899 0xf7, 0xbc, 0x23, 0xaa, 0xd4, 0xc1, 0xc9, 0x55 };
900 int i;
902 result = derive_key(CALG_DES, &hKey, 0);
903 if (!result) {
904 /* rsaenh compiled without OpenSSL */
905 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
906 return;
909 dwMode = CRYPT_MODE_ECB;
910 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
911 ok(result, "%08x\n", GetLastError());
913 dwLen = sizeof(DWORD);
914 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
915 ok(result, "%08x\n", GetLastError());
917 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
919 dwLen = 13;
920 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
921 ok(result, "%08x\n", GetLastError());
923 ok(!memcmp(pbData, des, sizeof(des)), "DES encryption failed!\n");
925 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
926 ok(result, "%08x\n", GetLastError());
928 for (i=0; i<4; i++)
930 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
932 dwLen = cTestData[i].enclen;
933 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
934 ok(result, "%08x\n", GetLastError());
935 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
936 memcpy(enc_data, pbData, cTestData[i].buflen);
938 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
939 ok(result, "%08x\n", GetLastError());
940 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
941 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
942 if((dwLen != cTestData[i].enclen) ||
943 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
945 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
946 printBytes("got",pbData,dwLen);
949 /* Test bad data:
950 Decrypting a block of bad data with Final = TRUE should restore the
951 initial state of the key as well as decrypting a block of good data.
954 /* Changing key state by setting Final = FALSE */
955 dwLen = cTestData[i].buflen;
956 memcpy(pbData, enc_data, cTestData[i].buflen);
957 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
958 ok(result, "%08x\n", GetLastError());
960 /* Restoring key state by decrypting bad_data with Final = TRUE */
961 memcpy(bad_data, enc_data, cTestData[i].buflen);
962 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
963 SetLastError(0xdeadbeef);
964 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
965 ok(!result, "CryptDecrypt should failed!\n");
966 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
967 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
968 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
970 /* Checking key state */
971 dwLen = cTestData[i].buflen;
972 memcpy(pbData, enc_data, cTestData[i].buflen);
973 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
974 ok(result, "%08x\n", GetLastError());
975 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
976 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
977 if((dwLen != cTestData[i].enclen) ||
978 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
980 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
981 printBytes("got",pbData,dwLen);
985 result = CryptDestroyKey(hKey);
986 ok(result, "%08x\n", GetLastError());
988 /* Windows >= XP changed the way DES keys are derived, this test ensures we don't break that */
989 derive_key(CALG_DES, &hKey, 56);
991 dwMode = CRYPT_MODE_ECB;
992 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
993 ok(result, "%08x\n", GetLastError());
995 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
997 dwLen = 13;
998 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
999 ok(result, "%08x\n", GetLastError());
1001 ok(!memcmp(pbData, des, sizeof(des)) || broken(!memcmp(pbData, des_old_behavior, sizeof(des))) /* <= 2000 */,
1002 "DES encryption failed!\n");
1004 result = CryptDestroyKey(hKey);
1005 ok(result, "%08x\n", GetLastError());
1008 static void test_3des(void)
1010 HCRYPTKEY hKey;
1011 BOOL result;
1012 DWORD dwLen;
1013 unsigned char pbData[16], enc_data[16], bad_data[16];
1014 static const BYTE des3[16] = {
1015 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
1016 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
1017 int i;
1019 result = derive_key(CALG_3DES, &hKey, 0);
1020 if (!result) return;
1022 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
1024 dwLen = 13;
1025 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
1026 ok(result, "%08x\n", GetLastError());
1028 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
1030 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1031 ok(result, "%08x\n", GetLastError());
1033 for (i=0; i<4; i++)
1035 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
1037 dwLen = cTestData[i].enclen;
1038 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
1039 ok(result, "%08x\n", GetLastError());
1040 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1041 memcpy(enc_data, pbData, cTestData[i].buflen);
1043 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1044 ok(result, "%08x\n", GetLastError());
1045 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1046 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
1047 if((dwLen != cTestData[i].enclen) ||
1048 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1050 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1051 printBytes("got",pbData,dwLen);
1054 /* Test bad data:
1055 Decrypting a block of bad data with Final = TRUE should restore the
1056 initial state of the key as well as decrypting a block of good data.
1059 /* Changing key state by setting Final = FALSE */
1060 dwLen = cTestData[i].buflen;
1061 memcpy(pbData, enc_data, cTestData[i].buflen);
1062 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
1063 ok(result, "%08x\n", GetLastError());
1065 /* Restoring key state by decrypting bad_data with Final = TRUE */
1066 memcpy(bad_data, enc_data, cTestData[i].buflen);
1067 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
1068 SetLastError(0xdeadbeef);
1069 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
1070 ok(!result, "CryptDecrypt should failed!\n");
1071 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
1072 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1073 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1075 /* Checking key state */
1076 dwLen = cTestData[i].buflen;
1077 memcpy(pbData, enc_data, cTestData[i].buflen);
1078 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1079 ok(result, "%08x\n", GetLastError());
1080 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1081 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1082 if((dwLen != cTestData[i].enclen) ||
1083 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1085 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1086 printBytes("got",pbData,dwLen);
1089 result = CryptDestroyKey(hKey);
1090 ok(result, "%08x\n", GetLastError());
1093 static void test_aes(int keylen)
1095 HCRYPTKEY hKey;
1096 BOOL result;
1097 DWORD dwLen, dwMode;
1098 unsigned char pbData[48], enc_data[16], bad_data[16];
1099 int i;
1100 static const BYTE aes_plain[32] = {
1101 "AES Test With 2 Blocks Of Data." };
1102 static const BYTE aes_cbc_enc[3][48] = {
1103 /* 128 bit key encrypted text */
1104 { 0xfe, 0x85, 0x3b, 0xe1, 0xf5, 0xe1, 0x58, 0x75, 0xd5, 0xa9, 0x74, 0xe3, 0x09, 0xea, 0xa5, 0x04,
1105 0x23, 0x35, 0xa2, 0x3b, 0x5c, 0xf1, 0x6c, 0x6f, 0xb9, 0xcd, 0x64, 0x06, 0x3e, 0x41, 0x83, 0xef,
1106 0x2a, 0xfe, 0xea, 0xb5, 0x6c, 0x17, 0x20, 0x79, 0x8c, 0x51, 0x3e, 0x56, 0xed, 0xe1, 0x47, 0x68 },
1107 /* 192 bit key encrypted text */
1108 { 0x6b, 0xf0, 0xfd, 0x32, 0xee, 0xc6, 0x06, 0x13, 0xa8, 0xe6, 0x3c, 0x81, 0x85, 0xb8, 0x2e, 0xa1,
1109 0xd4, 0x3b, 0xe8, 0x22, 0xa5, 0x74, 0x4a, 0xbe, 0x9d, 0xcf, 0xcc, 0x37, 0x26, 0x19, 0x5a, 0xd1,
1110 0x7f, 0x76, 0xbf, 0x94, 0x28, 0xce, 0x27, 0x21, 0x61, 0x87, 0xeb, 0xb9, 0x8b, 0xa8, 0xb4, 0x57 },
1111 /* 256 bit key encrypted text */
1112 { 0x20, 0x57, 0x17, 0x0b, 0x17, 0x76, 0xd8, 0x3b, 0x26, 0x90, 0x8b, 0x4c, 0xf2, 0x00, 0x79, 0x33,
1113 0x29, 0x2b, 0x13, 0x9c, 0xe2, 0x95, 0x09, 0xc1, 0xcd, 0x20, 0x87, 0x22, 0x32, 0x70, 0x9d, 0x75,
1114 0x9a, 0x94, 0xf5, 0x76, 0x5c, 0xb1, 0x62, 0x2c, 0xe1, 0x76, 0x7c, 0x86, 0x73, 0xe6, 0x7a, 0x23 }
1116 switch (keylen)
1118 case 256:
1119 result = derive_key(CALG_AES_256, &hKey, 0);
1120 i = 2;
1121 break;
1122 case 192:
1123 result = derive_key(CALG_AES_192, &hKey, 0);
1124 i = 1;
1125 break;
1126 default:
1127 case 128:
1128 result = derive_key(CALG_AES_128, &hKey, 0);
1129 i = 0;
1130 break;
1132 if (!result) return;
1134 dwLen = sizeof(aes_plain);
1135 memcpy(pbData, aes_plain, dwLen);
1136 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, sizeof(pbData));
1137 ok(result, "Expected OK, got last error %d\n", GetLastError());
1138 ok(dwLen == 48, "Expected dwLen 48, got %d\n", dwLen);
1139 todo_wine
1140 ok(!memcmp(aes_cbc_enc[i], pbData, dwLen), "Expected equal data sequences\n");
1142 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1143 ok(result && dwLen == 32 && !memcmp(aes_plain, pbData, dwLen),
1144 "%08x, dwLen: %d\n", GetLastError(), dwLen);
1146 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
1148 /* Does AES provider support salt? */
1149 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1150 ok((!result && GetLastError() == NTE_BAD_KEY) || result /* Win7 */,
1151 "expected NTE_BAD_KEY, got %08x\n", GetLastError());
1152 if (result)
1153 ok(!dwLen, "unexpected salt length %d\n", dwLen);
1155 /* test default chaining mode */
1156 dwMode = 0xdeadbeef;
1157 dwLen = sizeof(dwMode);
1158 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1159 ok(result, "%08x\n", GetLastError());
1160 todo_wine
1161 ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining\n");
1163 dwLen = 13;
1164 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
1165 ok(result, "%08x\n", GetLastError());
1167 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1168 ok(result, "%08x\n", GetLastError());
1170 for (i=0; i<4; i++)
1172 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
1174 dwLen = cTestData[i].enclen;
1175 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
1176 ok(result, "%08x\n", GetLastError());
1177 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1178 memcpy(enc_data, pbData, cTestData[i].buflen);
1180 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1181 ok(result, "%08x\n", GetLastError());
1182 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1183 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1184 if((dwLen != cTestData[i].enclen) ||
1185 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1187 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1188 printBytes("got",pbData,dwLen);
1191 /* Test bad data:
1192 Decrypting a block of bad data with Final = TRUE should restore the
1193 initial state of the key as well as decrypting a block of good data.
1196 /* Changing key state by setting Final = FALSE */
1197 dwLen = cTestData[i].buflen;
1198 memcpy(pbData, enc_data, cTestData[i].buflen);
1199 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
1200 ok(result, "%08x\n", GetLastError());
1202 /* Restoring key state by decrypting bad_data with Final = TRUE */
1203 memcpy(bad_data, enc_data, cTestData[i].buflen);
1204 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
1205 SetLastError(0xdeadbeef);
1206 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
1207 ok(!result, "CryptDecrypt should failed!\n");
1208 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
1209 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1210 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1212 /* Checking key state */
1213 dwLen = cTestData[i].buflen;
1214 memcpy(pbData, enc_data, cTestData[i].buflen);
1215 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1216 ok(result, "%08x\n", GetLastError());
1217 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1218 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1219 if((dwLen != cTestData[i].enclen) ||
1220 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1222 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1223 printBytes("got",pbData,dwLen);
1226 result = CryptDestroyKey(hKey);
1227 ok(result, "%08x\n", GetLastError());
1230 static void test_sha2(void)
1232 static const unsigned char sha256hash[32] = {
1233 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
1234 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
1235 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
1236 0x1a, 0x08
1238 static const unsigned char sha384hash[48] = {
1239 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
1240 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
1241 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
1242 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
1243 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
1245 static const unsigned char sha512hash[64] = {
1246 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1247 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1248 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1249 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1250 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1251 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1252 0xb7, 0xf4, 0x81, 0xd4
1254 unsigned char pbData[2048];
1255 BOOL result;
1256 HCRYPTHASH hHash;
1257 BYTE pbHashValue[64];
1258 DWORD hashlen, len;
1259 int i;
1261 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1263 /* SHA-256 hash */
1264 SetLastError(0xdeadbeef);
1265 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1266 if (!result && GetLastError() == NTE_BAD_ALGID) {
1267 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1268 return;
1270 ok(result, "%08x\n", GetLastError());
1271 if (result) {
1272 len = sizeof(DWORD);
1273 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1274 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1276 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1277 ok(result, "%08x\n", GetLastError());
1279 len = 32;
1280 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1281 ok(result, "%08x\n", GetLastError());
1283 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1285 result = CryptDestroyHash(hHash);
1286 ok(result, "%08x\n", GetLastError());
1289 /* SHA-384 hash */
1290 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1291 ok(result, "%08x\n", GetLastError());
1292 if (result) {
1293 len = sizeof(DWORD);
1294 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1295 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1297 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1298 ok(result, "%08x\n", GetLastError());
1300 len = 48;
1301 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1302 ok(result, "%08x\n", GetLastError());
1304 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1306 result = CryptDestroyHash(hHash);
1307 ok(result, "%08x\n", GetLastError());
1310 /* SHA-512 hash */
1311 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1312 ok(result, "%08x\n", GetLastError());
1313 if (result) {
1314 len = sizeof(DWORD);
1315 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1316 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1318 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1319 ok(result, "%08x\n", GetLastError());
1321 len = 64;
1322 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1323 ok(result, "%08x\n", GetLastError());
1325 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1327 result = CryptDestroyHash(hHash);
1328 ok(result, "%08x\n", GetLastError());
1332 static void test_rc2(void)
1334 static const BYTE rc2_40_encrypted[16] = {
1335 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1336 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1337 static const BYTE rc2_128_encrypted[] = {
1338 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
1339 0xb6,0x66 };
1340 HCRYPTHASH hHash;
1341 HCRYPTKEY hKey;
1342 BOOL result;
1343 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
1344 BYTE *pbTemp;
1345 unsigned char pbData[2000], pbHashValue[16];
1346 int i;
1348 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1350 /* MD2 Hashing */
1351 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1352 if (!result) {
1353 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1354 } else {
1355 CRYPT_INTEGER_BLOB salt;
1357 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1358 ok(result, "%08x\n", GetLastError());
1360 dwLen = 16;
1361 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1362 ok(result, "%08x\n", GetLastError());
1364 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1365 ok(result, "%08x\n", GetLastError());
1367 dwLen = sizeof(DWORD);
1368 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1369 ok(result, "%08x\n", GetLastError());
1371 /* test default chaining mode */
1372 dwMode = 0xdeadbeef;
1373 dwLen = sizeof(dwMode);
1374 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1375 ok(result, "%08x\n", GetLastError());
1376 ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining mode\n");
1378 dwMode = CRYPT_MODE_CBC;
1379 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1380 ok(result, "%08x\n", GetLastError());
1382 dwLen = sizeof(DWORD);
1383 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1384 ok(result, "%08x\n", GetLastError());
1386 dwModeBits = 0xdeadbeef;
1387 dwLen = sizeof(DWORD);
1388 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1389 ok(result, "%08x\n", GetLastError());
1390 ok(dwModeBits ==
1391 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1392 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
1393 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1394 " got %08x\n", dwModeBits);
1396 dwLen = sizeof(DWORD);
1397 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1398 ok(result, "%08x\n", GetLastError());
1400 dwLen = sizeof(DWORD);
1401 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1402 ok(result, "%08x\n", GetLastError());
1404 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1405 ok(result, "%08x\n", GetLastError());
1406 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1407 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1408 HeapFree(GetProcessHeap(), 0, pbTemp);
1410 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1411 ok(result, "%08x\n", GetLastError());
1412 /* The default salt length is always 11... */
1413 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1414 /* and the default salt is always empty. */
1415 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1416 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1417 for (i=0; i<dwLen; i++)
1418 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1419 HeapFree(GetProcessHeap(), 0, pbTemp);
1421 dwLen = sizeof(DWORD);
1422 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1424 result = CryptDestroyHash(hHash);
1425 ok(result, "%08x\n", GetLastError());
1427 dwDataLen = 13;
1428 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1429 ok(result, "%08x\n", GetLastError());
1431 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1433 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1434 ok(result, "%08x\n", GetLastError());
1435 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1436 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1437 HeapFree(GetProcessHeap(), 0, pbTemp);
1439 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1440 ok(result, "%08x\n", GetLastError());
1442 /* Setting the salt also succeeds... */
1443 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1444 ok(result, "setting salt failed: %08x\n", GetLastError());
1445 /* but the resulting salt length is now zero? */
1446 dwLen = 0;
1447 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1448 ok(result, "%08x\n", GetLastError());
1449 ok(dwLen == 0 ||
1450 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1451 "unexpected salt length %d\n", dwLen);
1452 /* What sizes salt can I set? */
1453 salt.pbData = pbData;
1454 for (i=0; i<24; i++)
1456 salt.cbData = i;
1457 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1458 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1459 /* The returned salt length is the same as the set salt length */
1460 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1461 ok(result, "%08x\n", GetLastError());
1462 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1464 salt.cbData = 25;
1465 SetLastError(0xdeadbeef);
1466 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1467 ok(!result ||
1468 broken(result), /* Win9x, WinMe, NT4, W2K */
1469 "%08x\n", GetLastError());
1471 result = CryptDestroyKey(hKey);
1472 ok(result, "%08x\n", GetLastError());
1475 /* Again, but test setting the effective key len */
1476 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1478 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1479 if (!result) {
1480 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1481 } else {
1482 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1483 ok(result, "%08x\n", GetLastError());
1485 dwLen = 16;
1486 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1487 ok(result, "%08x\n", GetLastError());
1489 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1490 ok(result, "%08x\n", GetLastError());
1492 SetLastError(0xdeadbeef);
1493 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1494 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1495 dwKeyLen = 0;
1496 SetLastError(0xdeadbeef);
1497 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1498 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1499 dwKeyLen = 1025;
1500 SetLastError(0xdeadbeef);
1501 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1502 ok(!result, "CryptSetKeyParam failed: %08x\n", GetLastError());
1504 dwLen = sizeof(dwKeyLen);
1505 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1506 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1507 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1508 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1510 dwKeyLen = 128;
1511 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1512 ok(result, "%d\n", GetLastError());
1514 dwLen = sizeof(dwKeyLen);
1515 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1516 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1517 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1518 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1520 result = CryptDestroyHash(hHash);
1521 ok(result, "%08x\n", GetLastError());
1523 dwDataLen = 13;
1524 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1525 ok(result, "%08x\n", GetLastError());
1527 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1528 "RC2 encryption failed!\n");
1530 /* Oddly enough this succeeds, though it should have no effect */
1531 dwKeyLen = 40;
1532 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1533 ok(result, "%d\n", GetLastError());
1535 result = CryptDestroyKey(hKey);
1536 ok(result, "%08x\n", GetLastError());
1540 static void test_rc4(void)
1542 static const BYTE rc4[16] = {
1543 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1544 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1545 BOOL result;
1546 HCRYPTHASH hHash;
1547 HCRYPTKEY hKey;
1548 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1549 unsigned char pbData[2000], *pbTemp;
1550 unsigned char pszBuffer[256];
1551 int i;
1553 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1555 /* MD2 Hashing */
1556 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1557 if (!result) {
1558 /* rsaenh compiled without OpenSSL */
1559 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1560 } else {
1561 CRYPT_INTEGER_BLOB salt;
1563 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1564 ok(result, "%08x\n", GetLastError());
1566 dwLen = 16;
1567 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1568 ok(result, "%08x\n", GetLastError());
1570 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1571 ok(result, "%08x\n", GetLastError());
1573 dwLen = sizeof(DWORD);
1574 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1575 ok(result, "%08x\n", GetLastError());
1577 dwLen = sizeof(DWORD);
1578 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1579 ok(result, "%08x\n", GetLastError());
1581 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1582 ok(result, "%08x\n", GetLastError());
1583 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1584 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1585 HeapFree(GetProcessHeap(), 0, pbTemp);
1587 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1588 ok(result, "%08x\n", GetLastError());
1589 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1590 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1591 HeapFree(GetProcessHeap(), 0, pbTemp);
1593 dwLen = sizeof(DWORD);
1594 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1596 result = CryptDestroyHash(hHash);
1597 ok(result, "%08x\n", GetLastError());
1599 dwDataLen = 16;
1600 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1601 ok(result, "%08x\n", GetLastError());
1602 dwDataLen = 16;
1603 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1604 ok(result, "%08x\n", GetLastError());
1606 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1608 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1609 ok(result, "%08x\n", GetLastError());
1611 /* Setting the salt also succeeds... */
1612 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1613 ok(result, "setting salt failed: %08x\n", GetLastError());
1614 /* but the resulting salt length is now zero? */
1615 dwLen = 0;
1616 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1617 ok(result, "%08x\n", GetLastError());
1618 ok(dwLen == 0 ||
1619 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1620 "unexpected salt length %d\n", dwLen);
1621 /* What sizes salt can I set? */
1622 salt.pbData = pbData;
1623 for (i=0; i<24; i++)
1625 salt.cbData = i;
1626 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1627 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1628 /* The returned salt length is the same as the set salt length */
1629 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1630 ok(result, "%08x\n", GetLastError());
1631 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1633 salt.cbData = 25;
1634 SetLastError(0xdeadbeef);
1635 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1636 ok(!result ||
1637 broken(result), /* Win9x, WinMe, NT4, W2K */
1638 "%08x\n", GetLastError());
1640 result = CryptDestroyKey(hKey);
1641 ok(result, "%08x\n", GetLastError());
1645 static void test_hmac(void) {
1646 HCRYPTKEY hKey;
1647 HCRYPTHASH hHash;
1648 BOOL result;
1649 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1650 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1651 DWORD dwLen;
1652 BYTE abData[256];
1653 static const BYTE hmac[16] = {
1654 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1655 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1656 int i;
1658 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1660 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1662 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1663 ok(result, "%08x\n", GetLastError());
1664 if (!result) return;
1666 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1667 ok(result, "%08x\n", GetLastError());
1669 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1670 ok(result, "%08x\n", GetLastError());
1672 dwLen = sizeof(abData)/sizeof(BYTE);
1673 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1674 ok(result, "%08x\n", GetLastError());
1676 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1678 result = CryptDestroyHash(hHash);
1679 ok(result, "%08x\n", GetLastError());
1681 result = CryptDestroyKey(hKey);
1682 ok(result, "%08x\n", GetLastError());
1684 /* Provoke errors */
1685 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1686 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1689 static void test_mac(void) {
1690 HCRYPTKEY hKey;
1691 HCRYPTHASH hHash;
1692 BOOL result;
1693 DWORD dwLen;
1694 BYTE abData[256], abEnc[264];
1695 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1696 int i;
1698 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1699 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1701 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1703 dwLen = 256;
1704 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1705 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1707 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1708 ok(result, "%08x\n", GetLastError());
1709 if (!result) return;
1711 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1712 ok(result, "%08x\n", GetLastError());
1714 dwLen = sizeof(abData)/sizeof(BYTE);
1715 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1716 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1718 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1720 result = CryptDestroyHash(hHash);
1721 ok(result, "%08x\n", GetLastError());
1723 result = CryptDestroyKey(hKey);
1724 ok(result, "%08x\n", GetLastError());
1726 /* Provoke errors */
1727 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1729 SetLastError(0xdeadbeef);
1730 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1731 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1732 broken(result), /* Win9x, WinMe, NT4, W2K */
1733 "%08x\n", GetLastError());
1735 result = CryptDestroyKey(hKey);
1736 ok(result, "%08x\n", GetLastError());
1739 static void test_import_private(void)
1741 DWORD dwLen, dwVal;
1742 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1743 BOOL result;
1744 static BYTE abSessionKey[148] = {
1745 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1746 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1747 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1748 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1749 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1750 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1751 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1752 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1753 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1754 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1755 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1756 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1757 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1758 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1759 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1760 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1761 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1762 0x04, 0x8c, 0x49, 0x92
1764 static BYTE abEncryptedMessage[12] = {
1765 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1766 0x1c, 0xfd, 0xde, 0x71
1768 BLOBHEADER *blobHeader = (BLOBHEADER *)abPlainPrivateKey;
1769 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(blobHeader+1);
1771 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1772 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1773 if (!result) {
1774 /* rsaenh compiled without OpenSSL */
1775 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1776 return;
1779 dwLen = (DWORD)sizeof(abSessionKey);
1780 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1781 ok(result, "%08x\n", GetLastError());
1782 if (!result) return;
1784 dwVal = 0xdeadbeef;
1785 dwLen = sizeof(DWORD);
1786 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1787 ok(result, "%08x\n", GetLastError());
1788 ok(dwVal ==
1789 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1790 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1791 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1792 " got %08x\n", dwVal);
1794 dwLen = (DWORD)sizeof(abEncryptedMessage);
1795 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1796 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1797 "%08x, len: %d\n", GetLastError(), dwLen);
1798 CryptDestroyKey(hSessionKey);
1800 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1802 dwLen = (DWORD)sizeof(abSessionKey);
1803 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1804 ok(result, "%08x\n", GetLastError());
1805 CryptDestroyKey(hSessionKey);
1806 if (!result) return;
1808 dwLen = (DWORD)sizeof(abSessionKey);
1809 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1810 ok(result, "%08x\n", GetLastError());
1811 if (!result) return;
1813 CryptDestroyKey(hSessionKey);
1814 CryptDestroyKey(hKeyExchangeKey);
1816 /* Test importing a private key with a buffer that's smaller than the
1817 * actual buffer. The private exponent can be omitted, its length is
1818 * inferred from the passed-in length parameter.
1820 dwLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
1821 rsaPubKey->bitlen / 8 + 5 * rsaPubKey->bitlen / 16;
1822 for (; dwLen < sizeof(abPlainPrivateKey); dwLen++)
1824 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1825 ok(result, "CryptImportKey failed at size %d: %d (%08x)\n", dwLen,
1826 GetLastError(), GetLastError());
1827 if (result)
1828 CryptDestroyKey(hKeyExchangeKey);
1832 static void test_verify_signature(void) {
1833 HCRYPTHASH hHash;
1834 HCRYPTKEY hPubSignKey;
1835 BYTE abData[] = "Wine rocks!";
1836 BOOL result;
1837 BYTE abPubKey[148] = {
1838 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1839 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1840 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1841 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1842 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1843 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1844 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1845 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1846 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1847 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1848 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1849 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1850 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1851 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1852 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1853 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1854 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1855 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1856 0xe1, 0x21, 0x50, 0xac
1858 /* md2 with hash oid */
1859 BYTE abSignatureMD2[128] = {
1860 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1861 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1862 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1863 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1864 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1865 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1866 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1867 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1868 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1869 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1870 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1871 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1872 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1873 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1874 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1875 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1877 /* md2 without hash oid */
1878 BYTE abSignatureMD2NoOID[128] = {
1879 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1880 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1881 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1882 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1883 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1884 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1885 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1886 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1887 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1888 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1889 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1890 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1891 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1892 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1893 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1894 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1896 /* md4 with hash oid */
1897 BYTE abSignatureMD4[128] = {
1898 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1899 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1900 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1901 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1902 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1903 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1904 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1905 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1906 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1907 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1908 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1909 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1910 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1911 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1912 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1913 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1915 /* md4 without hash oid */
1916 BYTE abSignatureMD4NoOID[128] = {
1917 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1918 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1919 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1920 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1921 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1922 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1923 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1924 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1925 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1926 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1927 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1928 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1929 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1930 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1931 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1932 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1934 /* md5 with hash oid */
1935 BYTE abSignatureMD5[128] = {
1936 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1937 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1938 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1939 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1940 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1941 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1942 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1943 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1944 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1945 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1946 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1947 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1948 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1949 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1950 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1951 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1953 /* md5 without hash oid */
1954 BYTE abSignatureMD5NoOID[128] = {
1955 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1956 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1957 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1958 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1959 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1960 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1961 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1962 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1963 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1964 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1965 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1966 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1967 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1968 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1969 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1970 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1972 /* sha with hash oid */
1973 BYTE abSignatureSHA[128] = {
1974 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1975 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1976 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1977 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1978 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1979 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1980 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1981 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1982 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1983 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1984 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1985 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1986 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1987 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1988 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1989 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1991 /* sha without hash oid */
1992 BYTE abSignatureSHANoOID[128] = {
1993 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1994 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1995 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1996 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1997 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1998 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1999 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
2000 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
2001 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
2002 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
2003 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
2004 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
2005 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
2006 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
2007 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
2008 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
2011 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
2012 ok(result, "%08x\n", GetLastError());
2013 if (!result) return;
2015 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
2016 ok(result, "%08x\n", GetLastError());
2017 if (!result) return;
2019 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2020 ok(result, "%08x\n", GetLastError());
2021 if (!result) return;
2023 /*check that a NULL pointer signature is correctly handled*/
2024 result = CryptVerifySignatureA(hHash, NULL, 128, hPubSignKey, NULL, 0);
2025 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
2026 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
2027 if (result) return;
2029 /* check that we get a bad signature error when the signature is too short*/
2030 SetLastError(0xdeadbeef);
2031 result = CryptVerifySignatureA(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
2032 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
2033 broken(result), /* Win9x, WinMe, NT4 */
2034 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2036 result = CryptVerifySignatureA(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
2037 ok(result, "%08x\n", GetLastError());
2038 if (!result) return;
2040 /* It seems that CPVerifySignature doesn't care about the OID at all. */
2041 result = CryptVerifySignatureA(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
2042 ok(result, "%08x\n", GetLastError());
2043 if (!result) return;
2045 result = CryptVerifySignatureA(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2046 ok(result, "%08x\n", GetLastError());
2047 if (!result) return;
2049 CryptDestroyHash(hHash);
2051 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
2052 ok(result, "%08x\n", GetLastError());
2053 if (!result) return;
2055 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2056 ok(result, "%08x\n", GetLastError());
2057 if (!result) return;
2059 result = CryptVerifySignatureA(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
2060 ok(result, "%08x\n", GetLastError());
2061 if (!result) return;
2063 result = CryptVerifySignatureA(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, 0);
2064 ok(result, "%08x\n", GetLastError());
2065 if (!result) return;
2067 result = CryptVerifySignatureA(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2068 ok(result, "%08x\n", GetLastError());
2069 if (!result) return;
2071 CryptDestroyHash(hHash);
2073 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
2074 ok(result, "%08x\n", GetLastError());
2075 if (!result) return;
2077 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2078 ok(result, "%08x\n", GetLastError());
2079 if (!result) return;
2081 result = CryptVerifySignatureA(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
2082 ok(result, "%08x\n", GetLastError());
2083 if (!result) return;
2085 result = CryptVerifySignatureA(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, 0);
2086 ok(result, "%08x\n", GetLastError());
2087 if (!result) return;
2089 result = CryptVerifySignatureA(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2090 ok(result, "%08x\n", GetLastError());
2091 if (!result) return;
2093 CryptDestroyHash(hHash);
2095 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
2096 ok(result, "%08x\n", GetLastError());
2097 if (!result) return;
2099 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2100 ok(result, "%08x\n", GetLastError());
2101 if (!result) return;
2103 result = CryptVerifySignatureA(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
2104 ok(result, "%08x\n", GetLastError());
2105 if (!result) return;
2107 result = CryptVerifySignatureA(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, 0);
2108 ok(result, "%08x\n", GetLastError());
2109 if (!result) return;
2111 result = CryptVerifySignatureA(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2112 ok(result, "%08x\n", GetLastError());
2113 if (!result) return;
2115 CryptDestroyHash(hHash);
2116 CryptDestroyKey(hPubSignKey);
2119 static void test_rsa_encrypt(void)
2121 HCRYPTKEY hRSAKey;
2122 BYTE abData[2048] = "Wine rocks!";
2123 BOOL result;
2124 DWORD dwVal, dwLen;
2126 /* It is allowed to use the key exchange key for encryption/decryption */
2127 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
2128 ok (result, "%08x\n", GetLastError());
2129 if (!result) return;
2131 dwLen = 12;
2132 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
2133 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
2134 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
2135 dwLen = 12;
2136 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
2137 ok (result, "%08x\n", GetLastError());
2138 if (!result) return;
2140 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
2141 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
2143 dwVal = 0xdeadbeef;
2144 dwLen = sizeof(DWORD);
2145 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2146 ok(result, "%08x\n", GetLastError());
2147 ok(dwVal ==
2148 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2149 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2150 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2151 " got %08x\n", dwVal);
2153 /* An RSA key doesn't support salt */
2154 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
2155 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
2156 "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
2158 /* The key exchange key's public key may be exported.. */
2159 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2160 ok(result, "%08x\n", GetLastError());
2161 /* but its private key may not be. */
2162 SetLastError(0xdeadbeef);
2163 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2164 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
2165 broken(result), /* Win9x/NT4 */
2166 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
2167 /* Setting the permissions of the key exchange key isn't allowed, either. */
2168 dwVal |= CRYPT_EXPORT;
2169 SetLastError(0xdeadbeef);
2170 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2171 ok(!result &&
2172 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
2173 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
2175 CryptDestroyKey(hRSAKey);
2177 /* It is not allowed to use the signature key for encryption/decryption */
2178 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
2179 ok (result, "%08x\n", GetLastError());
2180 if (!result) return;
2182 dwVal = 0xdeadbeef;
2183 dwLen = sizeof(DWORD);
2184 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2185 ok(result, "%08x\n", GetLastError());
2186 ok(dwVal ==
2187 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2188 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2189 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2190 " got %08x\n", dwVal);
2192 /* The signature key's public key may also be exported.. */
2193 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2194 ok(result, "%08x\n", GetLastError());
2195 /* but its private key may not be. */
2196 SetLastError(0xdeadbeef);
2197 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2198 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
2199 broken(result), /* Win9x/NT4 */
2200 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
2201 /* Setting the permissions of the signature key isn't allowed, either. */
2202 dwVal |= CRYPT_EXPORT;
2203 SetLastError(0xdeadbeef);
2204 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2205 ok(!result &&
2206 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
2207 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
2209 dwLen = 12;
2210 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
2211 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
2213 CryptDestroyKey(hRSAKey);
2216 static void test_import_export(void)
2218 DWORD dwLen, dwDataLen, dwVal;
2219 HCRYPTKEY hPublicKey, hPrivKey;
2220 BOOL result;
2221 ALG_ID algID;
2222 BYTE emptyKey[2048], *exported_key;
2223 static BYTE abPlainPublicKey[84] = {
2224 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
2225 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
2226 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
2227 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2228 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2229 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2230 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2231 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2232 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2233 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2234 0x11, 0x11, 0x11, 0x11
2236 static BYTE priv_key_with_high_bit[] = {
2237 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2238 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2239 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2240 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2241 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2242 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2243 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2244 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2245 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2246 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2247 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2248 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2249 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2250 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2251 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2252 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2253 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2254 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2255 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2256 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2257 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2258 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2259 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2260 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2261 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2262 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2263 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2264 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2265 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2266 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2267 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2268 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2269 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2270 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2271 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2272 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2273 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2274 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2275 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2276 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2277 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2278 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2279 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2280 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2281 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2282 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2283 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2284 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2285 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2286 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2287 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2288 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2289 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2290 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2291 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2292 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2293 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2294 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2295 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2296 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2297 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2298 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2299 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2300 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2301 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2302 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2303 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2304 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2305 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2306 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2307 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2308 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2309 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2310 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2311 0xb6, 0x5f, 0x01, 0x5e
2313 static const BYTE expected_exported_priv_key[] = {
2314 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2315 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2316 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2317 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2318 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2319 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2320 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2321 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2322 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2323 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2324 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2325 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2326 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2327 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2328 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2329 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2330 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2331 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2332 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2333 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2334 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2335 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2336 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2337 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2338 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2339 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2340 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2341 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2342 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2343 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2344 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2345 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2346 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2347 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2348 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2349 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2350 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2351 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2352 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2353 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2354 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2355 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2356 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2357 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2358 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2359 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2360 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2361 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2362 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2363 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2364 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2365 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2366 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2367 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2368 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2369 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2370 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2371 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2372 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2373 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2374 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2375 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2376 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2377 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2378 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2379 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2380 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2381 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2382 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2383 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2384 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2385 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2386 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2387 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2388 0xb6, 0x5f, 0x01, 0x5e
2391 dwLen=84;
2392 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2393 ok(result, "failed to import the public key\n");
2395 dwDataLen=sizeof(algID);
2396 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2397 ok(result, "failed to get the KP_ALGID from the imported public key\n");
2398 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2400 dwVal = 0xdeadbeef;
2401 dwDataLen = sizeof(DWORD);
2402 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2403 ok(result, "%08x\n", GetLastError());
2404 ok(dwVal ==
2405 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2406 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2407 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2408 " got %08x\n", dwVal);
2409 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2410 ok(result, "failed to export the fresh imported public key\n");
2411 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2412 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2414 CryptDestroyKey(hPublicKey);
2416 result = CryptImportKey(hProv, priv_key_with_high_bit,
2417 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2418 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2420 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2421 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2422 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2423 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2424 &dwDataLen);
2425 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2427 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2428 dwDataLen);
2429 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2430 "unexpected value\n");
2432 HeapFree(GetProcessHeap(), 0, exported_key);
2434 CryptDestroyKey(hPrivKey);
2437 static void test_import_hmac(void)
2439 /* Test cases from RFC 2202, section 3 */
2440 static const struct rfc2202_test_case {
2441 const char *key;
2442 DWORD key_len;
2443 const char *data;
2444 const DWORD data_len;
2445 const char *digest;
2446 } cases[] = {
2447 { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2448 "\x0b\x0b\x0b\x0b", 20,
2449 "Hi There", 8,
2450 "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2451 "\xf1\x46\xbe\x00" },
2452 { "Jefe", 4,
2453 "what do ya want for nothing?", 28,
2454 "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2455 "\x25\x9a\x7c\x79" },
2456 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2457 "\xaa\xaa\xaa\xaa", 20,
2458 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2459 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2460 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2461 "\xdd\xdd", 50,
2462 "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2463 "\x63\xf1\x75\xd3" },
2464 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2465 "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2466 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2467 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2468 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2469 "\xcd\xcd", 50,
2470 "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2471 "\x2d\x72\x35\xda" },
2472 { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2473 "\x0c\x0c\x0c\x0c", 20,
2474 "Test With Truncation", 20,
2475 "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2476 "\x4a\x9a\x5a\x04" },
2477 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
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",
2483 "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2484 "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2485 "\xed\x40\x21\x12" },
2486 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2487 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2488 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2489 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2490 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2492 "Test Using Larger Than Block-Size Key and Larger "
2493 "Than One Block-Size Data", 73,
2494 "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2495 "\xbb\xff\x1a\x91" }
2497 DWORD i;
2499 for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++)
2501 const struct rfc2202_test_case *test_case = &cases[i];
2502 DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2503 BYTE *blob = HeapAlloc(GetProcessHeap(), 0, size);
2505 if (blob)
2507 BLOBHEADER *header = (BLOBHEADER *)blob;
2508 DWORD *key_len = (DWORD *)(header + 1);
2509 BYTE *key_bytes = (BYTE *)(key_len + 1);
2510 BOOL result;
2511 HCRYPTKEY key;
2513 header->bType = PLAINTEXTKEYBLOB;
2514 header->bVersion = CUR_BLOB_VERSION;
2515 header->reserved = 0;
2516 header->aiKeyAlg = CALG_RC2;
2517 *key_len = test_case->key_len;
2518 memcpy(key_bytes, test_case->key, *key_len);
2519 result = CryptImportKey(hProv, blob, size, 0, CRYPT_IPSEC_HMAC_KEY, &key);
2520 ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
2521 if (result)
2523 HCRYPTHASH hash;
2524 HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2525 BYTE digest[20];
2526 DWORD digest_size;
2528 result = CryptCreateHash(hProv, CALG_HMAC, key, 0, &hash);
2529 ok(result, "CryptCreateHash failed on test case %d: %08x\n", i, GetLastError());
2530 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2531 ok(result, "CryptSetHashParam failed on test case %d: %08x\n", i, GetLastError());
2532 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2533 ok(result, "CryptHashData failed on test case %d: %08x\n", i, GetLastError());
2534 digest_size = sizeof(digest);
2535 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2536 ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
2537 ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected value on test case %d\n", i);
2538 CryptDestroyHash(hash);
2539 CryptDestroyKey(key);
2541 HeapFree(GetProcessHeap(), 0, blob);
2546 static void test_schannel_provider(void)
2548 HCRYPTPROV hProv;
2549 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2550 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2551 BOOL result;
2552 DWORD dwLen;
2553 SCHANNEL_ALG saSChannelAlg;
2554 CRYPT_DATA_BLOB data_blob;
2555 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2556 BYTE abTLS1Master[140] = {
2557 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2558 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2559 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2560 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2561 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2562 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2563 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2564 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2565 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2566 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2567 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2568 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2569 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2570 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2571 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2572 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2573 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2574 0xd3, 0x1e, 0x82, 0xb3
2576 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2577 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2578 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2579 BYTE abClientFinished[16] = "client finished";
2580 BYTE abData[16] = "Wine rocks!";
2581 BYTE abMD5Hash[16];
2582 static const BYTE abEncryptedData[16] = {
2583 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2584 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2586 static const BYTE abPRF[16] = {
2587 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2588 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2590 static const BYTE abMD5[16] = {
2591 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2592 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2595 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2596 if (!result)
2598 win_skip("no PROV_RSA_SCHANNEL support\n");
2599 return;
2601 ok (result, "%08x\n", GetLastError());
2602 if (result)
2603 CryptReleaseContext(hProv, 0);
2605 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2606 ok (result, "%08x\n", GetLastError());
2607 if (!result) return;
2609 /* To get deterministic results, we import the TLS1 master secret (which
2610 * is typically generated from a random generator). Therefore, we need
2611 * an RSA key. */
2612 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2613 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2614 ok (result, "%08x\n", GetLastError());
2615 if (!result) return;
2617 dwLen = (DWORD)sizeof(abTLS1Master);
2618 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2619 ok (result, "%08x\n", GetLastError());
2620 if (!result) return;
2622 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2623 * (Keys can only be derived from hashes, not from other keys.)
2624 * The hash can't be created yet because the key doesn't have the client
2625 * random or server random set.
2627 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2628 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER,
2629 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2631 /* Setting the TLS1 client and server random parameters, as well as the
2632 * MAC and encryption algorithm parameters. */
2633 data_blob.cbData = 33;
2634 data_blob.pbData = abClientSecret;
2635 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2636 ok (result, "%08x\n", GetLastError());
2637 if (!result) return;
2639 data_blob.cbData = 33;
2640 data_blob.pbData = abServerSecret;
2641 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2642 ok (result, "%08x\n", GetLastError());
2643 if (!result) return;
2645 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2646 ok (result, "%08x\n", GetLastError());
2647 if (!result) return;
2649 /* Deriving the server write encryption key from the master hash can't
2650 * succeed before the encryption key algorithm is set.
2652 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2653 ok (!result && GetLastError() == NTE_BAD_FLAGS,
2654 "expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2656 CryptDestroyHash(hMasterHash);
2658 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2659 saSChannelAlg.Algid = CALG_DES;
2660 saSChannelAlg.cBits = 64;
2661 saSChannelAlg.dwFlags = 0;
2662 saSChannelAlg.dwReserved = 0;
2663 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2664 ok (result, "%08x\n", GetLastError());
2665 if (!result) return;
2667 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2668 saSChannelAlg.Algid = CALG_MD5;
2669 saSChannelAlg.cBits = 128;
2670 saSChannelAlg.dwFlags = 0;
2671 saSChannelAlg.dwReserved = 0;
2672 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2673 ok (result, "%08x\n", GetLastError());
2674 if (!result) return;
2676 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2677 ok (result, "%08x\n", GetLastError());
2678 if (!result) return;
2680 /* Deriving the server write encryption key from the master hash */
2681 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2682 ok (result, "%08x\n", GetLastError());
2683 if (!result) return;
2685 /* Encrypting some data with the server write encryption key and checking the result. */
2686 dwLen = 12;
2687 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2688 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2690 /* Second test case: Test the TLS1 pseudo random number function. */
2691 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2692 ok (result, "%08x\n", GetLastError());
2693 if (!result) return;
2695 /* Set the label and seed parameters for the random number function */
2696 data_blob.cbData = 36;
2697 data_blob.pbData = abHashedHandshakes;
2698 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2699 ok (result, "%08x\n", GetLastError());
2700 if (!result) return;
2702 data_blob.cbData = 15;
2703 data_blob.pbData = abClientFinished;
2704 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2705 ok (result, "%08x\n", GetLastError());
2706 if (!result) return;
2708 /* Generate some pseudo random bytes and check if they are correct. */
2709 dwLen = (DWORD)sizeof(abData);
2710 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2711 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2712 "%08x\n", GetLastError());
2714 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2715 * Hash some data with the HMAC. Compare results. */
2716 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2717 ok (result, "%08x\n", GetLastError());
2718 if (!result) return;
2720 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2721 ok (result, "%08x\n", GetLastError());
2722 if (!result) return;
2724 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2725 ok (result, "%08x\n", GetLastError());
2726 if (!result) return;
2728 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2729 ok (result, "%08x\n", GetLastError());
2730 if (!result) return;
2732 dwLen = (DWORD)sizeof(abMD5Hash);
2733 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2734 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2736 CryptDestroyHash(hHMAC);
2737 CryptDestroyHash(hTLS1PRF);
2738 CryptDestroyHash(hMasterHash);
2739 CryptDestroyKey(hServerWriteMACKey);
2740 CryptDestroyKey(hServerWriteKey);
2741 CryptDestroyKey(hRSAKey);
2742 CryptDestroyKey(hMasterSecret);
2743 CryptReleaseContext(hProv, 0);
2744 CryptAcquireContextA(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2747 /* Test that a key can be used to encrypt data and exported, and that, when
2748 * the exported key is imported again, can be used to decrypt the original
2749 * data again.
2751 static void test_rsa_round_trip(void)
2753 static const char test_string[] = "Well this is a fine how-do-you-do.";
2754 HCRYPTPROV prov;
2755 HCRYPTKEY signKey, keyExchangeKey;
2756 BOOL result;
2757 BYTE data[256], *exportedKey;
2758 DWORD dataLen, keyLen;
2760 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2761 CRYPT_DELETEKEYSET);
2763 /* Generate a new key... */
2764 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2765 CRYPT_NEWKEYSET);
2766 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
2767 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2768 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2769 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2770 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2771 /* encrypt some data with it... */
2772 memcpy(data, test_string, strlen(test_string) + 1);
2773 dataLen = strlen(test_string) + 1;
2774 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2775 sizeof(data));
2776 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2777 broken(GetLastError() == NTE_PERM /* NT4 */),
2778 "CryptEncrypt failed: %08x\n", GetLastError());
2779 /* export the key... */
2780 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2781 &keyLen);
2782 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2783 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2784 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2785 &keyLen);
2786 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2787 /* destroy the key... */
2788 CryptDestroyKey(keyExchangeKey);
2789 CryptDestroyKey(signKey);
2790 /* import the key again... */
2791 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2792 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2793 HeapFree(GetProcessHeap(), 0, exportedKey);
2794 /* and decrypt the data encrypted with the original key with the imported
2795 * key.
2797 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2798 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2799 broken(GetLastError() == NTE_PERM /* NT4 */),
2800 "CryptDecrypt failed: %08x\n", GetLastError());
2801 if (result)
2803 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2804 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2806 CryptDestroyKey(keyExchangeKey);
2807 CryptReleaseContext(prov, 0);
2809 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2810 CRYPT_DELETEKEYSET);
2813 static void test_enum_container(void)
2815 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2816 DWORD dwBufferLen;
2817 BOOL result, fFound = FALSE;
2819 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2820 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2821 SetLastError(0xdeadbeef);
2822 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2823 ok (result, "%08x\n", GetLastError());
2824 ok (dwBufferLen == MAX_PATH + 1 ||
2825 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2826 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2828 /* If the result fits into abContainerName dwBufferLen is left untouched */
2829 dwBufferLen = (DWORD)sizeof(abContainerName);
2830 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2831 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2833 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2834 do {
2835 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2836 dwBufferLen = (DWORD)sizeof(abContainerName);
2837 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2839 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2842 static BYTE signBlob[] = {
2843 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2844 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2845 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2846 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2847 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2848 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2849 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2850 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2851 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2852 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2853 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2854 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2855 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2856 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2857 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2858 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2859 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2860 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2861 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2862 0xb6,0x85,0x86,0x07 };
2864 static void test_null_provider(void)
2866 HCRYPTPROV prov;
2867 HCRYPTKEY key;
2868 BOOL result;
2869 DWORD keySpec, dataLen,dwParam;
2870 char szName[MAX_PATH];
2872 result = CryptAcquireContextA(NULL, szContainer, NULL, 0, 0);
2873 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2874 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2875 result = CryptAcquireContextA(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2876 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2877 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2878 result = CryptAcquireContextA(NULL, szContainer, NULL, PROV_RSA_FULL,
2879 CRYPT_DELETEKEYSET);
2880 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2881 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2882 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2883 CRYPT_DELETEKEYSET);
2884 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2885 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2886 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2887 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2888 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2890 /* Delete the default container. */
2891 CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2892 /* Once you've deleted the default container you can't open it as if it
2893 * already exists.
2895 result = CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2896 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2897 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2898 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2899 result = CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL,
2900 CRYPT_VERIFYCONTEXT);
2901 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
2902 if (!result) return;
2903 dataLen = sizeof(keySpec);
2904 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2905 if (result)
2906 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2907 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2908 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2909 * supported, you can't get the keys from this container.
2911 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2912 ok(!result && GetLastError() == NTE_NO_KEY,
2913 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2914 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2915 ok(!result && GetLastError() == NTE_NO_KEY,
2916 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2917 result = CryptReleaseContext(prov, 0);
2918 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2919 /* You can create a new default container. */
2920 result = CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL,
2921 CRYPT_NEWKEYSET);
2922 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
2923 /* But you still can't get the keys (until one's been generated.) */
2924 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2925 ok(!result && GetLastError() == NTE_NO_KEY,
2926 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2927 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2928 ok(!result && GetLastError() == NTE_NO_KEY,
2929 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2930 CryptReleaseContext(prov, 0);
2931 CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2933 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2934 CRYPT_DELETEKEYSET);
2935 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2936 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2937 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2938 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2939 CRYPT_VERIFYCONTEXT);
2940 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2941 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2942 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
2943 CRYPT_NEWKEYSET);
2944 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
2945 if (!result) return;
2946 /* Test provider parameters getter */
2947 dataLen = sizeof(dwParam);
2948 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2949 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2950 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2951 dataLen = sizeof(dwParam);
2952 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2953 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2954 "Expected 0, got 0x%08X\n",dwParam);
2955 dataLen = sizeof(dwParam);
2956 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2957 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2958 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2959 dataLen = sizeof(keySpec);
2960 SetLastError(0xdeadbeef);
2961 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2962 if (!result && GetLastError() == NTE_BAD_TYPE)
2963 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2964 else
2965 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2966 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2967 /* PP_CONTAINER parameter */
2968 dataLen = sizeof(szName);
2969 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2970 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2971 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2972 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2973 /* PP_UNIQUE_CONTAINER parameter */
2974 dataLen = sizeof(szName);
2975 SetLastError(0xdeadbeef);
2976 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2977 if (!result && GetLastError() == NTE_BAD_TYPE)
2979 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2981 else
2983 char container[MAX_PATH];
2985 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2986 uniquecontainer(container);
2987 todo_wine
2989 ok(dataLen == strlen(container)+1 ||
2990 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2991 "Expected a param length of 70, got %d\n", dataLen);
2992 ok(!strcmp(container, szName) ||
2993 broken(!strcmp(szName, szContainer)) /* WinME */,
2994 "Wrong container name : %s\n", szName);
2997 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2998 ok(!result && GetLastError() == NTE_NO_KEY,
2999 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3000 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3001 ok(!result && GetLastError() == NTE_NO_KEY,
3002 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3004 /* Importing a key exchange blob.. */
3005 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
3006 0, 0, &key);
3007 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3008 CryptDestroyKey(key);
3009 /* allows access to the key exchange key.. */
3010 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3011 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3012 CryptDestroyKey(key);
3013 /* but not to the private key. */
3014 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3015 ok(!result && GetLastError() == NTE_NO_KEY,
3016 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3017 CryptReleaseContext(prov, 0);
3018 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3019 CRYPT_DELETEKEYSET);
3021 /* Whereas importing a sign blob.. */
3022 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3023 CRYPT_NEWKEYSET);
3024 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3025 if (!result) return;
3026 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
3027 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3028 CryptDestroyKey(key);
3029 /* doesn't allow access to the key exchange key.. */
3030 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3031 ok(!result && GetLastError() == NTE_NO_KEY,
3032 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3033 /* but does to the private key. */
3034 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3035 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3036 CryptDestroyKey(key);
3037 CryptReleaseContext(prov, 0);
3039 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3040 CRYPT_DELETEKEYSET);
3042 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
3043 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3044 CRYPT_NEWKEYSET);
3045 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3046 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
3047 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
3048 CryptDestroyKey(key);
3049 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3050 ok(!result, "expected CryptGetUserKey to fail\n");
3051 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3052 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
3053 CryptDestroyKey(key);
3054 CryptReleaseContext(prov, 0);
3056 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3057 CRYPT_DELETEKEYSET);
3059 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
3060 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3061 CRYPT_NEWKEYSET);
3062 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3063 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
3064 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
3065 CryptDestroyKey(key);
3066 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3067 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
3068 CryptDestroyKey(key);
3069 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3070 ok(!result, "expected CryptGetUserKey to fail\n");
3071 CryptReleaseContext(prov, 0);
3073 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3074 CRYPT_DELETEKEYSET);
3076 /* test for the bug in accessing the user key in a container
3078 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3079 CRYPT_NEWKEYSET);
3080 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3081 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
3082 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
3083 CryptDestroyKey(key);
3084 CryptReleaseContext(prov,0);
3085 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,0);
3086 ok(result, "CryptAcquireContextA failed: 0x%08x\n", GetLastError());
3087 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3088 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
3089 CryptDestroyKey(key);
3090 CryptReleaseContext(prov, 0);
3092 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3093 CRYPT_DELETEKEYSET);
3095 /* test the machine key set */
3096 CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3097 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
3098 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3099 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
3100 ok(result, "CryptAcquireContextA with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
3101 CryptReleaseContext(prov, 0);
3102 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3103 CRYPT_MACHINE_KEYSET);
3104 ok(result, "CryptAcquireContextA with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
3105 CryptReleaseContext(prov,0);
3106 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3107 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
3108 ok(result, "CryptAcquireContextA with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
3109 GetLastError());
3110 result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3111 CRYPT_MACHINE_KEYSET);
3112 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
3113 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3117 static void test_key_permissions(void)
3119 HCRYPTKEY hKey1, hKey2;
3120 DWORD dwVal, dwLen;
3121 BOOL result;
3123 /* Create keys that are exportable */
3124 if (!init_base_environment(CRYPT_EXPORTABLE))
3125 return;
3127 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
3128 ok (result, "%08x\n", GetLastError());
3129 if (!result) return;
3131 dwVal = 0xdeadbeef;
3132 dwLen = sizeof(DWORD);
3133 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3134 ok(result, "%08x\n", GetLastError());
3135 ok(dwVal ==
3136 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
3137 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3138 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3139 " got %08x\n", dwVal);
3141 /* The key exchange key's public key may be exported.. */
3142 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
3143 ok(result, "%08x\n", GetLastError());
3144 /* and its private key may be too. */
3145 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
3146 ok(result, "%08x\n", GetLastError());
3147 /* Turning off the key's export permissions is "allowed".. */
3148 dwVal &= ~CRYPT_EXPORT;
3149 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
3150 ok(result ||
3151 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
3152 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
3153 "%08x\n", GetLastError());
3154 /* but it has no effect. */
3155 dwVal = 0xdeadbeef;
3156 dwLen = sizeof(DWORD);
3157 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3158 ok(result, "%08x\n", GetLastError());
3159 ok(dwVal ==
3160 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
3161 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3162 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3163 " got %08x\n", dwVal);
3164 /* Thus, changing the export flag of the key doesn't affect whether the key
3165 * may be exported.
3167 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
3168 ok(result, "%08x\n", GetLastError());
3170 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
3171 ok (result, "%08x\n", GetLastError());
3173 /* A subsequent get of the same key, into a different handle, also doesn't
3174 * show that the permissions have been changed.
3176 dwVal = 0xdeadbeef;
3177 dwLen = sizeof(DWORD);
3178 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3179 ok(result, "%08x\n", GetLastError());
3180 ok(dwVal ==
3181 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
3182 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3183 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3184 " got %08x\n", dwVal);
3186 CryptDestroyKey(hKey2);
3187 CryptDestroyKey(hKey1);
3189 clean_up_base_environment();
3192 static void test_key_initialization(void)
3194 DWORD dwLen;
3195 HCRYPTPROV prov1, prov2;
3196 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
3197 BOOL result;
3198 static BYTE abSessionKey[148] = {
3199 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
3200 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
3201 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
3202 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
3203 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
3204 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
3205 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
3206 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
3207 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
3208 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
3209 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
3210 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
3211 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
3212 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
3213 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
3214 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
3215 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
3216 0x04, 0x8c, 0x49, 0x92
3219 /* Like init_base_environment, but doesn't generate new keys, as they'll
3220 * be imported instead.
3222 if (!CryptAcquireContextA(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
3224 result = CryptAcquireContextA(&prov1, szContainer, szProvider, PROV_RSA_FULL,
3225 CRYPT_NEWKEYSET);
3226 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3228 dwLen = (DWORD)sizeof(abPlainPrivateKey);
3229 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
3230 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3232 dwLen = (DWORD)sizeof(abSessionKey);
3233 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
3234 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3236 /* Once the key has been imported, subsequently acquiring a context with
3237 * the same name will allow retrieving the key.
3239 result = CryptAcquireContextA(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
3240 ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3241 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
3242 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3243 if (result) CryptDestroyKey(hKey);
3244 CryptReleaseContext(prov2, 0);
3246 CryptDestroyKey(hSessionKey);
3247 CryptDestroyKey(hKeyExchangeKey);
3248 CryptReleaseContext(prov1, 0);
3249 CryptAcquireContextA(&prov1, szContainer, NULL, PROV_RSA_FULL,
3250 CRYPT_DELETEKEYSET);
3253 START_TEST(rsaenh)
3255 if (!init_base_environment(0))
3256 return;
3257 test_prov();
3258 test_gen_random();
3259 test_hashes();
3260 test_rc4();
3261 test_rc2();
3262 test_des();
3263 test_3des112();
3264 test_3des();
3265 test_hmac();
3266 test_mac();
3267 test_block_cipher_modes();
3268 test_import_private();
3269 test_verify_signature();
3270 test_rsa_encrypt();
3271 test_import_export();
3272 test_import_hmac();
3273 test_enum_container();
3274 clean_up_base_environment();
3275 test_key_permissions();
3276 test_key_initialization();
3277 test_schannel_provider();
3278 test_null_provider();
3279 test_rsa_round_trip();
3280 if (!init_aes_environment())
3281 return;
3282 test_aes(128);
3283 test_aes(192);
3284 test_aes(256);
3285 test_sha2();
3286 clean_up_aes_environment();