wineps: Fix a couple of typos in the path painting function.
[wine/testsucceed.git] / dlls / rsaenh / tests / rsaenh.c
blob4af3cdcc4337e86cb8bdbba10e94c5971d7f95cd
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 lstrcpy(unique, szContainer_md5);
88 lstrcat(unique, "_");
89 lstrcat(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 int 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 = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
131 ok(!result && (GetLastError()==NTE_BAD_FLAGS ||
132 broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */)),
133 "%d, %08x\n", result, GetLastError());
135 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
137 ok(GetLastError()==NTE_BAD_KEYSET ||
138 broken(GetLastError() == NTE_TEMPORARY_PROFILE /* some Win7 setups */) ||
139 broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */),
140 "%08x\n", GetLastError());
141 if (GetLastError()!=NTE_BAD_KEYSET)
143 win_skip("RSA full provider not available\n");
144 return 0;
146 result = CryptAcquireContext(&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 0;
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 1;
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 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
181 static int 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. Its different as to what
192 * its defined in the SDK on Windows XP.
193 * This provider is available on Windows XP, Windows 2003 and Vista. */
195 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
196 if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
198 win_skip("RSA_AES provider not supported\n");
199 return 0;
201 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
203 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
205 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
206 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
207 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
208 CRYPT_NEWKEYSET);
209 ok(result, "%08x\n", GetLastError());
210 if (!result) return 0;
211 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
212 ok(result, "%08x\n", GetLastError());
213 if (result) CryptDestroyKey(hKey);
214 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
215 ok(result, "%08x\n", GetLastError());
216 if (result) CryptDestroyKey(hKey);
218 return 1;
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 CryptAcquireContext(&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, "%08x\n", GetLastError());
452 len = sizeof(DWORD);
453 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
454 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
456 len = 16;
457 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
458 ok(result, "%08x\n", GetLastError());
460 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
462 result = CryptDestroyHash(hHash);
463 ok(result, "%08x\n", GetLastError());
465 /* MD5 Hashing */
466 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
467 ok(result, "%08x\n", GetLastError());
469 len = sizeof(DWORD);
470 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
471 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
473 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
474 ok(result, "%08x\n", GetLastError());
476 len = 16;
477 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
478 ok(result, "%08x\n", GetLastError());
480 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
482 result = CryptDestroyHash(hHash);
483 ok(result, "%08x\n", GetLastError());
485 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
486 ok(result, "%08x\n", GetLastError());
488 /* The hash is available even if CryptHashData hasn't been called */
489 len = 16;
490 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
491 ok(result, "%08x\n", GetLastError());
493 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
495 /* It's also stable: getting it twice results in the same value */
496 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
497 ok(result, "%08x\n", GetLastError());
499 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
501 /* Can't add data after the hash been retrieved */
502 SetLastError(0xdeadbeef);
503 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
504 ok(!result, "Expected failure\n");
505 ok(GetLastError() == NTE_BAD_HASH_STATE ||
506 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
507 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
509 /* You can still retrieve the hash, its value just hasn't changed */
510 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
511 ok(result, "%08x\n", GetLastError());
513 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
515 result = CryptDestroyHash(hHash);
516 ok(result, "%08x\n", GetLastError());
518 /* SHA1 Hashing */
519 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
520 ok(result, "%08x\n", GetLastError());
522 result = CryptHashData(hHash, pbData, 5, 0);
523 ok(result, "%08x\n", GetLastError());
525 if(pCryptDuplicateHash) {
526 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
527 ok(result, "%08x\n", GetLastError());
529 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
530 ok(result, "%08x\n", GetLastError());
532 len = sizeof(DWORD);
533 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
534 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
536 len = 20;
537 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
538 ok(result, "%08x\n", GetLastError());
540 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
542 result = CryptDestroyHash(hHashClone);
543 ok(result, "%08x\n", GetLastError());
546 result = CryptDestroyHash(hHash);
547 ok(result, "%08x\n", GetLastError());
549 /* The SHA-2 variants aren't supported in the RSA full provider */
550 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
551 ok(!result && GetLastError() == NTE_BAD_ALGID,
552 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
553 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
554 ok(!result && GetLastError() == NTE_BAD_ALGID,
555 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
556 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
557 ok(!result && GetLastError() == NTE_BAD_ALGID,
558 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
560 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
561 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
563 result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash);
564 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
566 /* release provider before using the hash */
567 result = CryptReleaseContext(prov, 0);
568 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
570 SetLastError(0xdeadbeef);
571 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
572 error = GetLastError();
573 ok(!result, "CryptHashData succeeded\n");
574 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
576 SetLastError(0xdeadbeef);
577 result = CryptDestroyHash(hHash);
578 error = GetLastError();
579 ok(!result, "CryptDestroyHash succeeded\n");
580 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
582 if (!pCryptDuplicateHash)
584 win_skip("CryptDuplicateHash is not available\n");
585 return;
588 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
589 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
591 result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
592 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
594 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
595 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
597 result = pCryptDuplicateHash(hHash, NULL, 0, &hHashClone);
598 ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
600 len = 20;
601 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
602 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
604 /* add data after duplicating the hash */
605 result = CryptHashData(hHash, (const BYTE *)"more data", sizeof("more data"), 0);
606 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
608 result = CryptDestroyHash(hHash);
609 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
611 result = CryptDestroyHash(hHashClone);
612 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
614 result = CryptReleaseContext(prov, 0);
615 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
617 /* Test CALG_SSL3_SHAMD5 */
618 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
619 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
621 /* Step 1: create an MD5 hash of the data */
622 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
623 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
624 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
625 ok(result, "%08x\n", GetLastError());
626 len = 16;
627 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
628 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
629 result = CryptDestroyHash(hHash);
630 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
631 /* Step 2: create a SHA1 hash of the data */
632 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
633 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
634 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
635 ok(result, "%08x\n", GetLastError());
636 len = 20;
637 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue + 16, &len, 0);
638 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
639 result = CryptDestroyHash(hHash);
640 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
641 /* Step 3: create a CALG_SSL3_SHAMD5 hash handle */
642 result = CryptCreateHash(hProv, CALG_SSL3_SHAMD5, 0, 0, &hHash);
643 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
644 /* Test that CryptHashData fails on this hash */
645 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
646 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
647 result = CryptSetHashParam(hHash, HP_HASHVAL, pbHashValue, 0);
648 ok(result, "%08x\n", GetLastError());
649 len = (DWORD)sizeof(abPlainPrivateKey);
650 result = CryptImportKey(hProv, abPlainPrivateKey, len, 0, 0, &hKeyExchangeKey);
651 ok(result, "%08x\n", GetLastError());
652 len = 0;
653 result = CryptSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &len);
654 ok(result, "%08x\n", GetLastError());
655 ok(len == 128, "expected len 128, got %d\n", len);
656 result = CryptSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, pbSigValue, &len);
657 ok(result, "%08x\n", GetLastError());
658 ok(!memcmp(pbSigValue, signed_ssl3_shamd5_hash, len), "unexpected value\n");
659 if (len != 128 || memcmp(pbSigValue, signed_ssl3_shamd5_hash, len))
661 printBytes("expected", signed_ssl3_shamd5_hash,
662 sizeof(signed_ssl3_shamd5_hash));
663 printBytes("got", pbSigValue, len);
665 result = CryptDestroyKey(hKeyExchangeKey);
666 ok(result, "CryptDestroyKey failed 0x%08x\n", GetLastError());
667 result = CryptDestroyHash(hHash);
668 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
669 result = CryptReleaseContext(prov, 0);
670 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
673 static void test_block_cipher_modes(void)
675 static const BYTE plain[23] = {
676 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
677 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
678 static const BYTE ecb[24] = {
679 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
680 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
681 static const BYTE cbc[24] = {
682 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
683 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
684 static const BYTE cfb[24] = {
685 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
686 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
687 HCRYPTKEY hKey;
688 BOOL result;
689 BYTE abData[24];
690 DWORD dwMode, dwLen;
692 result = derive_key(CALG_RC2, &hKey, 40);
693 if (!result) return;
695 memcpy(abData, plain, sizeof(plain));
697 dwMode = CRYPT_MODE_ECB;
698 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
699 ok(result, "%08x\n", GetLastError());
701 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
702 ok(result, "%08x\n", GetLastError());
703 ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
705 dwLen = 23;
706 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
707 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
708 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
710 SetLastError(ERROR_SUCCESS);
711 dwLen = 23;
712 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
713 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
714 "%08x, dwLen: %d\n", GetLastError(), dwLen);
716 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
717 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
718 "%08x, dwLen: %d\n", GetLastError(), dwLen);
720 dwMode = CRYPT_MODE_CBC;
721 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
722 ok(result, "%08x\n", GetLastError());
724 dwLen = 23;
725 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
726 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
727 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
729 dwLen = 23;
730 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
731 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
732 "%08x, dwLen: %d\n", GetLastError(), dwLen);
734 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
735 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
736 "%08x, dwLen: %d\n", GetLastError(), dwLen);
738 dwMode = CRYPT_MODE_CFB;
739 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
740 ok(result, "%08x\n", GetLastError());
742 dwLen = 16;
743 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
744 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
746 dwLen = 7;
747 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
748 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
749 "%08x, dwLen: %d\n", GetLastError(), dwLen);
751 dwLen = 8;
752 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
753 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
755 dwLen = 16;
756 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
757 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
758 "%08x, dwLen: %d\n", GetLastError(), dwLen);
760 dwMode = CRYPT_MODE_OFB;
761 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
762 ok(result, "%08x\n", GetLastError());
764 dwLen = 23;
765 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
766 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
768 CryptDestroyKey(hKey);
771 static void test_3des112(void)
773 HCRYPTKEY hKey;
774 BOOL result;
775 DWORD dwLen;
776 unsigned char pbData[16];
777 int i;
779 result = derive_key(CALG_3DES_112, &hKey, 0);
780 if (!result) {
781 /* rsaenh compiled without OpenSSL */
782 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
783 return;
786 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
788 dwLen = 13;
789 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
790 ok(result, "%08x\n", GetLastError());
792 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
793 ok(result, "%08x\n", GetLastError());
795 for (i=0; i<4; i++)
797 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
799 dwLen = cTestData[i].enclen;
800 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
801 ok(result, "%08x\n", GetLastError());
802 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
804 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
805 ok(result, "%08x\n", GetLastError());
806 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
807 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
808 if((dwLen != cTestData[i].enclen) ||
809 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
811 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
812 printBytes("got",pbData,dwLen);
815 result = CryptDestroyKey(hKey);
816 ok(result, "%08x\n", GetLastError());
819 static void test_des(void)
821 HCRYPTKEY hKey;
822 BOOL result;
823 DWORD dwLen, dwMode;
824 unsigned char pbData[16];
825 int i;
827 result = derive_key(CALG_DES, &hKey, 56);
828 if (!result) {
829 /* rsaenh compiled without OpenSSL */
830 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
831 return;
834 dwMode = CRYPT_MODE_ECB;
835 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
836 ok(result, "%08x\n", GetLastError());
838 dwLen = sizeof(DWORD);
839 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
840 ok(result, "%08x\n", GetLastError());
842 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
844 dwLen = 13;
845 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
846 ok(result, "%08x\n", GetLastError());
848 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
849 ok(result, "%08x\n", GetLastError());
851 for (i=0; i<4; i++)
853 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
855 dwLen = cTestData[i].enclen;
856 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
857 ok(result, "%08x\n", GetLastError());
858 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
860 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
861 ok(result, "%08x\n", GetLastError());
862 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
863 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
864 if((dwLen != cTestData[i].enclen) ||
865 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
867 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
868 printBytes("got",pbData,dwLen);
872 result = CryptDestroyKey(hKey);
873 ok(result, "%08x\n", GetLastError());
876 static void test_3des(void)
878 HCRYPTKEY hKey;
879 BOOL result;
880 DWORD dwLen;
881 unsigned char pbData[16];
882 static const BYTE des3[16] = {
883 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
884 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
885 int i;
887 result = derive_key(CALG_3DES, &hKey, 0);
888 if (!result) return;
890 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
892 dwLen = 13;
893 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
894 ok(result, "%08x\n", GetLastError());
896 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
898 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
899 ok(result, "%08x\n", GetLastError());
901 for (i=0; i<4; i++)
903 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
905 dwLen = cTestData[i].enclen;
906 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
907 ok(result, "%08x\n", GetLastError());
908 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
910 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
911 ok(result, "%08x\n", GetLastError());
912 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
913 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
914 if((dwLen != cTestData[i].enclen) ||
915 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
917 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
918 printBytes("got",pbData,dwLen);
921 result = CryptDestroyKey(hKey);
922 ok(result, "%08x\n", GetLastError());
925 static void test_aes(int keylen)
927 HCRYPTKEY hKey;
928 BOOL result;
929 DWORD dwLen;
930 unsigned char pbData[16];
931 int i;
933 switch (keylen)
935 case 256:
936 result = derive_key(CALG_AES_256, &hKey, 0);
937 break;
938 case 192:
939 result = derive_key(CALG_AES_192, &hKey, 0);
940 break;
941 default:
942 case 128:
943 result = derive_key(CALG_AES_128, &hKey, 0);
944 break;
946 if (!result) return;
948 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
950 /* Does AES provider support salt? */
951 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
952 ok((!result && GetLastError() == NTE_BAD_KEY) || result /* Win7 */,
953 "expected NTE_BAD_KEY, got %08x\n", GetLastError());
954 if (result)
955 ok(!dwLen, "unexpected salt length %d\n", dwLen);
957 dwLen = 13;
958 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
959 ok(result, "%08x\n", GetLastError());
961 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
962 ok(result, "%08x\n", GetLastError());
964 for (i=0; i<4; i++)
966 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
968 dwLen = cTestData[i].enclen;
969 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
970 ok(result, "%08x\n", GetLastError());
971 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
973 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
974 ok(result, "%08x\n", GetLastError());
975 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
976 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
977 if((dwLen != cTestData[i].enclen) ||
978 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
980 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
981 printBytes("got",pbData,dwLen);
984 result = CryptDestroyKey(hKey);
985 ok(result, "%08x\n", GetLastError());
988 static void test_sha2(void)
990 static const unsigned char sha256hash[32] = {
991 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
992 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
993 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
994 0x1a, 0x08
996 static const unsigned char sha384hash[48] = {
997 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
998 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
999 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
1000 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
1001 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
1003 static const unsigned char sha512hash[64] = {
1004 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1005 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1006 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1007 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1008 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1009 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1010 0xb7, 0xf4, 0x81, 0xd4
1012 unsigned char pbData[2048];
1013 BOOL result;
1014 HCRYPTHASH hHash;
1015 BYTE pbHashValue[64];
1016 DWORD hashlen, len;
1017 int i;
1019 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1021 /* SHA-256 hash */
1022 SetLastError(0xdeadbeef);
1023 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1024 if (!result && GetLastError() == NTE_BAD_ALGID) {
1025 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1026 return;
1028 ok(result, "%08x\n", GetLastError());
1029 if (result) {
1030 len = sizeof(DWORD);
1031 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1032 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1034 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1035 ok(result, "%08x\n", GetLastError());
1037 len = 32;
1038 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1039 ok(result, "%08x\n", GetLastError());
1041 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1043 result = CryptDestroyHash(hHash);
1044 ok(result, "%08x\n", GetLastError());
1047 /* SHA-384 hash */
1048 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1049 ok(result, "%08x\n", GetLastError());
1050 if (result) {
1051 len = sizeof(DWORD);
1052 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1053 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1055 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1056 ok(result, "%08x\n", GetLastError());
1058 len = 48;
1059 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1060 ok(result, "%08x\n", GetLastError());
1062 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1064 result = CryptDestroyHash(hHash);
1065 ok(result, "%08x\n", GetLastError());
1068 /* SHA-512 hash */
1069 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1070 ok(result, "%08x\n", GetLastError());
1071 if (result) {
1072 len = sizeof(DWORD);
1073 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1074 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1076 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1077 ok(result, "%08x\n", GetLastError());
1079 len = 64;
1080 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1081 ok(result, "%08x\n", GetLastError());
1083 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1085 result = CryptDestroyHash(hHash);
1086 ok(result, "%08x\n", GetLastError());
1090 static void test_rc2(void)
1092 static const BYTE rc2_40_encrypted[16] = {
1093 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1094 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1095 static const BYTE rc2_128_encrypted[] = {
1096 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
1097 0xb6,0x66 };
1098 HCRYPTHASH hHash;
1099 HCRYPTKEY hKey;
1100 BOOL result;
1101 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
1102 BYTE *pbTemp;
1103 unsigned char pbData[2000], pbHashValue[16];
1104 int i;
1106 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1108 /* MD2 Hashing */
1109 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1110 if (!result) {
1111 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1112 } else {
1113 CRYPT_INTEGER_BLOB salt;
1115 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1116 ok(result, "%08x\n", GetLastError());
1118 dwLen = 16;
1119 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1120 ok(result, "%08x\n", GetLastError());
1122 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1123 ok(result, "%08x\n", GetLastError());
1125 dwLen = sizeof(DWORD);
1126 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1127 ok(result, "%08x\n", GetLastError());
1129 dwMode = CRYPT_MODE_CBC;
1130 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1131 ok(result, "%08x\n", GetLastError());
1133 dwLen = sizeof(DWORD);
1134 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1135 ok(result, "%08x\n", GetLastError());
1137 dwModeBits = 0xdeadbeef;
1138 dwLen = sizeof(DWORD);
1139 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1140 ok(result, "%08x\n", GetLastError());
1141 ok(dwModeBits ==
1142 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1143 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
1144 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1145 " got %08x\n", dwModeBits);
1147 dwLen = sizeof(DWORD);
1148 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1149 ok(result, "%08x\n", GetLastError());
1151 dwLen = sizeof(DWORD);
1152 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1153 ok(result, "%08x\n", GetLastError());
1155 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1156 ok(result, "%08x\n", GetLastError());
1157 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1158 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1159 HeapFree(GetProcessHeap(), 0, pbTemp);
1161 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1162 ok(result, "%08x\n", GetLastError());
1163 /* The default salt length is always 11... */
1164 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1165 /* and the default salt is always empty. */
1166 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1167 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1168 for (i=0; i<dwLen; i++)
1169 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1170 HeapFree(GetProcessHeap(), 0, pbTemp);
1172 dwLen = sizeof(DWORD);
1173 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1175 result = CryptDestroyHash(hHash);
1176 ok(result, "%08x\n", GetLastError());
1178 dwDataLen = 13;
1179 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1180 ok(result, "%08x\n", GetLastError());
1182 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1184 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1185 ok(result, "%08x\n", GetLastError());
1186 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1187 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1188 HeapFree(GetProcessHeap(), 0, pbTemp);
1190 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1191 ok(result, "%08x\n", GetLastError());
1193 /* Setting the salt also succeeds... */
1194 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1195 ok(result, "setting salt failed: %08x\n", GetLastError());
1196 /* but the resulting salt length is now zero? */
1197 dwLen = 0;
1198 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1199 ok(result, "%08x\n", GetLastError());
1200 ok(dwLen == 0 ||
1201 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1202 "unexpected salt length %d\n", dwLen);
1203 /* What sizes salt can I set? */
1204 salt.pbData = pbData;
1205 for (i=0; i<24; i++)
1207 salt.cbData = i;
1208 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1209 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1210 /* The returned salt length is the same as the set salt length */
1211 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1212 ok(result, "%08x\n", GetLastError());
1213 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1215 salt.cbData = 25;
1216 SetLastError(0xdeadbeef);
1217 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1218 ok(!result ||
1219 broken(result), /* Win9x, WinMe, NT4, W2K */
1220 "%08x\n", GetLastError());
1222 result = CryptDestroyKey(hKey);
1223 ok(result, "%08x\n", GetLastError());
1226 /* Again, but test setting the effective key len */
1227 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1229 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1230 if (!result) {
1231 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1232 } else {
1233 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1234 ok(result, "%08x\n", GetLastError());
1236 dwLen = 16;
1237 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1238 ok(result, "%08x\n", GetLastError());
1240 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1241 ok(result, "%08x\n", GetLastError());
1243 SetLastError(0xdeadbeef);
1244 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1245 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1246 dwKeyLen = 0;
1247 SetLastError(0xdeadbeef);
1248 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1249 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1250 dwKeyLen = 1025;
1251 SetLastError(0xdeadbeef);
1252 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1253 ok(!result, "CryptSetKeyParam failed: %08x\n", GetLastError());
1255 dwLen = sizeof(dwKeyLen);
1256 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1257 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1258 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1259 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1261 dwKeyLen = 128;
1262 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1263 ok(result, "%d\n", GetLastError());
1265 dwLen = sizeof(dwKeyLen);
1266 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1267 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1268 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1269 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1271 result = CryptDestroyHash(hHash);
1272 ok(result, "%08x\n", GetLastError());
1274 dwDataLen = 13;
1275 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1276 ok(result, "%08x\n", GetLastError());
1278 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1279 "RC2 encryption failed!\n");
1281 /* Oddly enough this succeeds, though it should have no effect */
1282 dwKeyLen = 40;
1283 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1284 ok(result, "%d\n", GetLastError());
1286 result = CryptDestroyKey(hKey);
1287 ok(result, "%08x\n", GetLastError());
1291 static void test_rc4(void)
1293 static const BYTE rc4[16] = {
1294 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1295 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1296 BOOL result;
1297 HCRYPTHASH hHash;
1298 HCRYPTKEY hKey;
1299 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1300 unsigned char pbData[2000], *pbTemp;
1301 unsigned char pszBuffer[256];
1302 int i;
1304 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1306 /* MD2 Hashing */
1307 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1308 if (!result) {
1309 /* rsaenh compiled without OpenSSL */
1310 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1311 } else {
1312 CRYPT_INTEGER_BLOB salt;
1314 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1315 ok(result, "%08x\n", GetLastError());
1317 dwLen = 16;
1318 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1319 ok(result, "%08x\n", GetLastError());
1321 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1322 ok(result, "%08x\n", GetLastError());
1324 dwLen = sizeof(DWORD);
1325 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1326 ok(result, "%08x\n", GetLastError());
1328 dwLen = sizeof(DWORD);
1329 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1330 ok(result, "%08x\n", GetLastError());
1332 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1333 ok(result, "%08x\n", GetLastError());
1334 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1335 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1336 HeapFree(GetProcessHeap(), 0, pbTemp);
1338 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1339 ok(result, "%08x\n", GetLastError());
1340 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1341 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1342 HeapFree(GetProcessHeap(), 0, pbTemp);
1344 dwLen = sizeof(DWORD);
1345 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1347 result = CryptDestroyHash(hHash);
1348 ok(result, "%08x\n", GetLastError());
1350 dwDataLen = 16;
1351 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1352 ok(result, "%08x\n", GetLastError());
1353 dwDataLen = 16;
1354 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1355 ok(result, "%08x\n", GetLastError());
1357 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1359 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1360 ok(result, "%08x\n", GetLastError());
1362 /* Setting the salt also succeeds... */
1363 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1364 ok(result, "setting salt failed: %08x\n", GetLastError());
1365 /* but the resulting salt length is now zero? */
1366 dwLen = 0;
1367 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1368 ok(result, "%08x\n", GetLastError());
1369 ok(dwLen == 0 ||
1370 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1371 "unexpected salt length %d\n", dwLen);
1372 /* What sizes salt can I set? */
1373 salt.pbData = pbData;
1374 for (i=0; i<24; i++)
1376 salt.cbData = i;
1377 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1378 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1379 /* The returned salt length is the same as the set salt length */
1380 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1381 ok(result, "%08x\n", GetLastError());
1382 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1384 salt.cbData = 25;
1385 SetLastError(0xdeadbeef);
1386 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1387 ok(!result ||
1388 broken(result), /* Win9x, WinMe, NT4, W2K */
1389 "%08x\n", GetLastError());
1391 result = CryptDestroyKey(hKey);
1392 ok(result, "%08x\n", GetLastError());
1396 static void test_hmac(void) {
1397 HCRYPTKEY hKey;
1398 HCRYPTHASH hHash;
1399 BOOL result;
1400 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1401 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1402 DWORD dwLen;
1403 BYTE abData[256];
1404 static const BYTE hmac[16] = {
1405 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1406 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1407 int i;
1409 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1411 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1413 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1414 ok(result, "%08x\n", GetLastError());
1415 if (!result) return;
1417 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1418 ok(result, "%08x\n", GetLastError());
1420 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1421 ok(result, "%08x\n", GetLastError());
1423 dwLen = sizeof(abData)/sizeof(BYTE);
1424 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1425 ok(result, "%08x\n", GetLastError());
1427 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1429 result = CryptDestroyHash(hHash);
1430 ok(result, "%08x\n", GetLastError());
1432 result = CryptDestroyKey(hKey);
1433 ok(result, "%08x\n", GetLastError());
1435 /* Provoke errors */
1436 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1437 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1440 static void test_mac(void) {
1441 HCRYPTKEY hKey;
1442 HCRYPTHASH hHash;
1443 BOOL result;
1444 DWORD dwLen;
1445 BYTE abData[256], abEnc[264];
1446 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1447 int i;
1449 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1450 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1452 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1454 dwLen = 256;
1455 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1456 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1458 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1459 ok(result, "%08x\n", GetLastError());
1460 if (!result) return;
1462 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1463 ok(result, "%08x\n", GetLastError());
1465 dwLen = sizeof(abData)/sizeof(BYTE);
1466 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1467 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1469 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1471 result = CryptDestroyHash(hHash);
1472 ok(result, "%08x\n", GetLastError());
1474 result = CryptDestroyKey(hKey);
1475 ok(result, "%08x\n", GetLastError());
1477 /* Provoke errors */
1478 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1480 SetLastError(0xdeadbeef);
1481 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1482 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1483 broken(result), /* Win9x, WinMe, NT4, W2K */
1484 "%08x\n", GetLastError());
1486 result = CryptDestroyKey(hKey);
1487 ok(result, "%08x\n", GetLastError());
1490 static void test_import_private(void)
1492 DWORD dwLen, dwVal;
1493 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1494 BOOL result;
1495 static BYTE abSessionKey[148] = {
1496 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1497 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1498 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1499 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1500 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1501 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1502 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1503 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1504 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1505 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1506 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1507 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1508 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1509 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1510 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1511 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1512 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1513 0x04, 0x8c, 0x49, 0x92
1515 static BYTE abEncryptedMessage[12] = {
1516 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1517 0x1c, 0xfd, 0xde, 0x71
1519 BLOBHEADER *blobHeader = (BLOBHEADER *)abPlainPrivateKey;
1520 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(blobHeader+1);
1522 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1523 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1524 if (!result) {
1525 /* rsaenh compiled without OpenSSL */
1526 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1527 return;
1530 dwLen = (DWORD)sizeof(abSessionKey);
1531 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1532 ok(result, "%08x\n", GetLastError());
1533 if (!result) return;
1535 dwVal = 0xdeadbeef;
1536 dwLen = sizeof(DWORD);
1537 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1538 ok(result, "%08x\n", GetLastError());
1539 ok(dwVal ==
1540 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1541 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1542 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1543 " got %08x\n", dwVal);
1545 dwLen = (DWORD)sizeof(abEncryptedMessage);
1546 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1547 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1548 "%08x, len: %d\n", GetLastError(), dwLen);
1549 CryptDestroyKey(hSessionKey);
1551 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1553 dwLen = (DWORD)sizeof(abSessionKey);
1554 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1555 ok(result, "%08x\n", GetLastError());
1556 CryptDestroyKey(hSessionKey);
1557 if (!result) return;
1559 dwLen = (DWORD)sizeof(abSessionKey);
1560 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1561 ok(result, "%08x\n", GetLastError());
1562 if (!result) return;
1564 CryptDestroyKey(hSessionKey);
1565 CryptDestroyKey(hKeyExchangeKey);
1567 /* Test importing a private key with a buffer that's smaller than the
1568 * actual buffer. The private exponent can be omitted, its length is
1569 * inferred from the passed-in length parameter.
1571 dwLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
1572 rsaPubKey->bitlen / 8 + 5 * rsaPubKey->bitlen / 16;
1573 for (; dwLen < sizeof(abPlainPrivateKey); dwLen++)
1575 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1576 ok(result, "CryptImportKey failed at size %d: %d (%08x)\n", dwLen,
1577 GetLastError(), GetLastError());
1578 if (result)
1579 CryptDestroyKey(hKeyExchangeKey);
1583 static void test_verify_signature(void) {
1584 HCRYPTHASH hHash;
1585 HCRYPTKEY hPubSignKey;
1586 BYTE abData[] = "Wine rocks!";
1587 BOOL result;
1588 BYTE abPubKey[148] = {
1589 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1590 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1591 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1592 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1593 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1594 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1595 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1596 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1597 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1598 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1599 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1600 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1601 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1602 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1603 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1604 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1605 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1606 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1607 0xe1, 0x21, 0x50, 0xac
1609 /* md2 with hash oid */
1610 BYTE abSignatureMD2[128] = {
1611 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1612 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1613 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1614 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1615 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1616 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1617 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1618 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1619 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1620 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1621 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1622 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1623 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1624 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1625 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1626 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1628 /* md2 without hash oid */
1629 BYTE abSignatureMD2NoOID[128] = {
1630 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1631 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1632 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1633 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1634 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1635 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1636 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1637 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1638 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1639 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1640 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1641 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1642 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1643 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1644 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1645 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1647 /* md4 with hash oid */
1648 BYTE abSignatureMD4[128] = {
1649 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1650 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1651 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1652 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1653 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1654 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1655 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1656 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1657 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1658 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1659 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1660 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1661 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1662 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1663 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1664 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1666 /* md4 without hash oid */
1667 BYTE abSignatureMD4NoOID[128] = {
1668 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1669 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1670 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1671 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1672 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1673 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1674 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1675 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1676 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1677 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1678 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1679 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1680 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1681 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1682 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1683 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1685 /* md5 with hash oid */
1686 BYTE abSignatureMD5[128] = {
1687 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1688 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1689 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1690 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1691 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1692 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1693 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1694 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1695 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1696 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1697 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1698 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1699 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1700 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1701 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1702 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1704 /* md5 without hash oid */
1705 BYTE abSignatureMD5NoOID[128] = {
1706 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1707 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1708 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1709 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1710 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1711 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1712 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1713 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1714 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1715 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1716 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1717 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1718 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1719 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1720 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1721 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1723 /* sha with hash oid */
1724 BYTE abSignatureSHA[128] = {
1725 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1726 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1727 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1728 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1729 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1730 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1731 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1732 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1733 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1734 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1735 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1736 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1737 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1738 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1739 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1740 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1742 /* sha without hash oid */
1743 BYTE abSignatureSHANoOID[128] = {
1744 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1745 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1746 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1747 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1748 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1749 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1750 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1751 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1752 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1753 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1754 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1755 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1756 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1757 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1758 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1759 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1762 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1763 ok(result, "%08x\n", GetLastError());
1764 if (!result) return;
1766 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1767 ok(result, "%08x\n", GetLastError());
1768 if (!result) return;
1770 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1771 ok(result, "%08x\n", GetLastError());
1772 if (!result) return;
1774 /*check that a NULL pointer signature is correctly handled*/
1775 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1776 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1777 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1778 if (result) return;
1780 /* check that we get a bad signature error when the signature is too short*/
1781 SetLastError(0xdeadbeef);
1782 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1783 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1784 broken(result), /* Win9x, WinMe, NT4 */
1785 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1787 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1788 ok(result, "%08x\n", GetLastError());
1789 if (!result) return;
1791 /* It seems that CPVerifySignature doesn't care about the OID at all. */
1792 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1793 ok(result, "%08x\n", GetLastError());
1794 if (!result) return;
1796 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1797 ok(result, "%08x\n", GetLastError());
1798 if (!result) return;
1800 CryptDestroyHash(hHash);
1802 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1803 ok(result, "%08x\n", GetLastError());
1804 if (!result) return;
1806 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1807 ok(result, "%08x\n", GetLastError());
1808 if (!result) return;
1810 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1811 ok(result, "%08x\n", GetLastError());
1812 if (!result) return;
1814 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, 0);
1815 ok(result, "%08x\n", GetLastError());
1816 if (!result) return;
1818 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1819 ok(result, "%08x\n", GetLastError());
1820 if (!result) return;
1822 CryptDestroyHash(hHash);
1824 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1825 ok(result, "%08x\n", GetLastError());
1826 if (!result) return;
1828 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1829 ok(result, "%08x\n", GetLastError());
1830 if (!result) return;
1832 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1833 ok(result, "%08x\n", GetLastError());
1834 if (!result) return;
1836 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, 0);
1837 ok(result, "%08x\n", GetLastError());
1838 if (!result) return;
1840 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1841 ok(result, "%08x\n", GetLastError());
1842 if (!result) return;
1844 CryptDestroyHash(hHash);
1846 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1847 ok(result, "%08x\n", GetLastError());
1848 if (!result) return;
1850 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1851 ok(result, "%08x\n", GetLastError());
1852 if (!result) return;
1854 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1855 ok(result, "%08x\n", GetLastError());
1856 if (!result) return;
1858 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, 0);
1859 ok(result, "%08x\n", GetLastError());
1860 if (!result) return;
1862 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1863 ok(result, "%08x\n", GetLastError());
1864 if (!result) return;
1866 CryptDestroyHash(hHash);
1867 CryptDestroyKey(hPubSignKey);
1870 static void test_rsa_encrypt(void)
1872 HCRYPTKEY hRSAKey;
1873 BYTE abData[2048] = "Wine rocks!";
1874 BOOL result;
1875 DWORD dwVal, dwLen;
1877 /* It is allowed to use the key exchange key for encryption/decryption */
1878 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1879 ok (result, "%08x\n", GetLastError());
1880 if (!result) return;
1882 dwLen = 12;
1883 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1884 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1885 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1886 dwLen = 12;
1887 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1888 ok (result, "%08x\n", GetLastError());
1889 if (!result) return;
1891 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1892 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1894 dwVal = 0xdeadbeef;
1895 dwLen = sizeof(DWORD);
1896 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1897 ok(result, "%08x\n", GetLastError());
1898 ok(dwVal ==
1899 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1900 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1901 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1902 " got %08x\n", dwVal);
1904 /* An RSA key doesn't support salt */
1905 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1906 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
1907 "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
1909 /* The key exchange key's public key may be exported.. */
1910 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1911 ok(result, "%08x\n", GetLastError());
1912 /* but its private key may not be. */
1913 SetLastError(0xdeadbeef);
1914 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1915 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1916 broken(result), /* Win9x/NT4 */
1917 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1918 /* Setting the permissions of the key exchange key isn't allowed, either. */
1919 dwVal |= CRYPT_EXPORT;
1920 SetLastError(0xdeadbeef);
1921 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1922 ok(!result &&
1923 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1924 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1926 CryptDestroyKey(hRSAKey);
1928 /* It is not allowed to use the signature key for encryption/decryption */
1929 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1930 ok (result, "%08x\n", GetLastError());
1931 if (!result) return;
1933 dwVal = 0xdeadbeef;
1934 dwLen = sizeof(DWORD);
1935 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1936 ok(result, "%08x\n", GetLastError());
1937 ok(dwVal ==
1938 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1939 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1940 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1941 " got %08x\n", dwVal);
1943 /* The signature key's public key may also be exported.. */
1944 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1945 ok(result, "%08x\n", GetLastError());
1946 /* but its private key may not be. */
1947 SetLastError(0xdeadbeef);
1948 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1949 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1950 broken(result), /* Win9x/NT4 */
1951 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1952 /* Setting the permissions of the signature key isn't allowed, either. */
1953 dwVal |= CRYPT_EXPORT;
1954 SetLastError(0xdeadbeef);
1955 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1956 ok(!result &&
1957 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1958 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1960 dwLen = 12;
1961 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1962 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1964 CryptDestroyKey(hRSAKey);
1967 static void test_import_export(void)
1969 DWORD dwLen, dwDataLen, dwVal;
1970 HCRYPTKEY hPublicKey, hPrivKey;
1971 BOOL result;
1972 ALG_ID algID;
1973 BYTE emptyKey[2048], *exported_key;
1974 static BYTE abPlainPublicKey[84] = {
1975 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1976 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1977 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1978 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1979 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1980 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1981 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1982 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1983 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1984 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1985 0x11, 0x11, 0x11, 0x11
1987 static BYTE priv_key_with_high_bit[] = {
1988 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1989 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1990 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1991 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1992 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1993 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1994 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1995 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1996 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1997 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1998 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1999 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2000 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2001 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2002 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2003 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2004 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2005 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2006 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2007 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2008 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2009 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2010 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2011 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2012 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2013 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2014 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2015 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2016 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2017 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2018 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2019 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2020 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2021 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2022 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2023 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2024 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2025 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2026 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2027 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2028 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2029 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2030 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2031 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2032 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2033 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2034 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2035 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2036 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2037 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2038 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2039 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2040 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2041 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2042 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2043 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2044 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2045 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2046 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2047 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2048 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2049 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2050 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2051 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2052 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2053 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2054 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2055 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2056 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2057 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2058 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2059 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2060 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2061 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2062 0xb6, 0x5f, 0x01, 0x5e
2064 static const BYTE expected_exported_priv_key[] = {
2065 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2066 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2067 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2068 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2069 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2070 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2071 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2072 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2073 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2074 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2075 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2076 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2077 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2078 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2079 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2080 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2081 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2082 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2083 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2084 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2085 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2086 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2087 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2088 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2089 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2090 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2091 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2092 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2093 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2094 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2095 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2096 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2097 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2098 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2099 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2100 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2101 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2102 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2103 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2104 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2105 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2106 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2107 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2108 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2109 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2110 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2111 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2112 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2113 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2114 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2115 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2116 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2117 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2118 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2119 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2120 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2121 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2122 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2123 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2124 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2125 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2126 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2127 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2128 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2129 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2130 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2131 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2132 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2133 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2134 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2135 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2136 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2137 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2138 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2139 0xb6, 0x5f, 0x01, 0x5e
2142 dwLen=84;
2143 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2144 ok(result, "failed to import the public key\n");
2146 dwDataLen=sizeof(algID);
2147 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2148 ok(result, "failed to get the KP_ALGID from the imported public key\n");
2149 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2151 dwVal = 0xdeadbeef;
2152 dwDataLen = sizeof(DWORD);
2153 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2154 ok(result, "%08x\n", GetLastError());
2155 ok(dwVal ==
2156 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2157 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2158 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2159 " got %08x\n", dwVal);
2160 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2161 ok(result, "failed to export the fresh imported public key\n");
2162 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2163 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2165 CryptDestroyKey(hPublicKey);
2167 result = CryptImportKey(hProv, priv_key_with_high_bit,
2168 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2169 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2171 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2172 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2173 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2174 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2175 &dwDataLen);
2176 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2178 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2179 dwDataLen);
2180 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2181 "unexpected value\n");
2183 HeapFree(GetProcessHeap(), 0, exported_key);
2185 CryptDestroyKey(hPrivKey);
2188 static void test_import_hmac(void)
2190 /* Test cases from RFC 2202, section 3 */
2191 static const struct rfc2202_test_case {
2192 const char *key;
2193 DWORD key_len;
2194 const char *data;
2195 const DWORD data_len;
2196 const char *digest;
2197 } cases[] = {
2198 { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2199 "\x0b\x0b\x0b\x0b", 20,
2200 "Hi There", 8,
2201 "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2202 "\xf1\x46\xbe\x00" },
2203 { "Jefe", 4,
2204 "what do ya want for nothing?", 28,
2205 "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2206 "\x25\x9a\x7c\x79" },
2207 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2208 "\xaa\xaa\xaa\xaa", 20,
2209 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2210 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2211 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2212 "\xdd\xdd", 50,
2213 "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2214 "\x63\xf1\x75\xd3" },
2215 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2216 "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2217 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2218 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2219 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2220 "\xcd\xcd", 50,
2221 "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2222 "\x2d\x72\x35\xda" },
2223 { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2224 "\x0c\x0c\x0c\x0c", 20,
2225 "Test With Truncation", 20,
2226 "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2227 "\x4a\x9a\x5a\x04" },
2228 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2229 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2230 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2231 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2232 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2234 "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2235 "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2236 "\xed\x40\x21\x12" },
2237 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2238 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2239 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2240 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2241 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2243 "Test Using Larger Than Block-Size Key and Larger "
2244 "Than One Block-Size Data", 73,
2245 "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2246 "\xbb\xff\x1a\x91" }
2248 DWORD i;
2250 for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++)
2252 const struct rfc2202_test_case *test_case = &cases[i];
2253 DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2254 BYTE *blob = HeapAlloc(GetProcessHeap(), 0, size);
2256 if (blob)
2258 BLOBHEADER *header = (BLOBHEADER *)blob;
2259 DWORD *key_len = (DWORD *)(header + 1);
2260 BYTE *key_bytes = (BYTE *)(key_len + 1);
2261 BOOL result;
2262 HCRYPTKEY key;
2264 header->bType = PLAINTEXTKEYBLOB;
2265 header->bVersion = CUR_BLOB_VERSION;
2266 header->reserved = 0;
2267 header->aiKeyAlg = CALG_RC2;
2268 *key_len = test_case->key_len;
2269 memcpy(key_bytes, test_case->key, *key_len);
2270 result = CryptImportKey(hProv, blob, size, 0, CRYPT_IPSEC_HMAC_KEY, &key);
2271 ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
2272 if (result)
2274 HCRYPTHASH hash;
2275 HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2276 BYTE digest[20];
2277 DWORD digest_size;
2279 result = CryptCreateHash(hProv, CALG_HMAC, key, 0, &hash);
2280 ok(result, "CryptCreateHash failed on test case %d: %08x\n", i, GetLastError());
2281 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2282 ok(result, "CryptSetHashParam failed on test case %d: %08x\n", i, GetLastError());
2283 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2284 ok(result, "CryptHashData failed on test case %d: %08x\n", i, GetLastError());
2285 digest_size = sizeof(digest);
2286 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2287 ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
2288 ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected value on test case %d\n", i);
2289 CryptDestroyHash(hash);
2290 CryptDestroyKey(key);
2292 HeapFree(GetProcessHeap(), 0, blob);
2297 static void test_schannel_provider(void)
2299 HCRYPTPROV hProv;
2300 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2301 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2302 BOOL result;
2303 DWORD dwLen;
2304 SCHANNEL_ALG saSChannelAlg;
2305 CRYPT_DATA_BLOB data_blob;
2306 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2307 BYTE abTLS1Master[140] = {
2308 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2309 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2310 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2311 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2312 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2313 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2314 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2315 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2316 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2317 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2318 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2319 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2320 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2321 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2322 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2323 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2324 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2325 0xd3, 0x1e, 0x82, 0xb3
2327 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2328 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2329 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2330 BYTE abClientFinished[16] = "client finished";
2331 BYTE abData[16] = "Wine rocks!";
2332 BYTE abMD5Hash[16];
2333 static const BYTE abEncryptedData[16] = {
2334 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2335 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2337 static const BYTE abPRF[16] = {
2338 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2339 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2341 static const BYTE abMD5[16] = {
2342 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2343 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2346 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2347 if (!result)
2349 win_skip("no PROV_RSA_SCHANNEL support\n");
2350 return;
2352 ok (result, "%08x\n", GetLastError());
2353 if (result)
2354 CryptReleaseContext(hProv, 0);
2356 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2357 ok (result, "%08x\n", GetLastError());
2358 if (!result) return;
2360 /* To get deterministic results, we import the TLS1 master secret (which
2361 * is typically generated from a random generator). Therefore, we need
2362 * an RSA key. */
2363 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2364 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2365 ok (result, "%08x\n", GetLastError());
2366 if (!result) return;
2368 dwLen = (DWORD)sizeof(abTLS1Master);
2369 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2370 ok (result, "%08x\n", GetLastError());
2371 if (!result) return;
2373 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2374 * (Keys can only be derived from hashes, not from other keys.)
2375 * The hash can't be created yet because the key doesn't have the client
2376 * random or server random set.
2378 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2379 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER,
2380 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2382 /* Setting the TLS1 client and server random parameters, as well as the
2383 * MAC and encryption algorithm parameters. */
2384 data_blob.cbData = 33;
2385 data_blob.pbData = abClientSecret;
2386 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2387 ok (result, "%08x\n", GetLastError());
2388 if (!result) return;
2390 data_blob.cbData = 33;
2391 data_blob.pbData = abServerSecret;
2392 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2393 ok (result, "%08x\n", GetLastError());
2394 if (!result) return;
2396 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2397 ok (result, "%08x\n", GetLastError());
2398 if (!result) return;
2400 /* Deriving the server write encryption key from the master hash can't
2401 * succeed before the encryption key algorithm is set.
2403 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2404 ok (!result && GetLastError() == NTE_BAD_FLAGS,
2405 "expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2407 CryptDestroyHash(hMasterHash);
2409 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2410 saSChannelAlg.Algid = CALG_DES;
2411 saSChannelAlg.cBits = 64;
2412 saSChannelAlg.dwFlags = 0;
2413 saSChannelAlg.dwReserved = 0;
2414 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2415 ok (result, "%08x\n", GetLastError());
2416 if (!result) return;
2418 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2419 saSChannelAlg.Algid = CALG_MD5;
2420 saSChannelAlg.cBits = 128;
2421 saSChannelAlg.dwFlags = 0;
2422 saSChannelAlg.dwReserved = 0;
2423 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2424 ok (result, "%08x\n", GetLastError());
2425 if (!result) return;
2427 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2428 ok (result, "%08x\n", GetLastError());
2429 if (!result) return;
2431 /* Deriving the server write encryption key from the master hash */
2432 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2433 ok (result, "%08x\n", GetLastError());
2434 if (!result) return;
2436 /* Encrypting some data with the server write encryption key and checking the result. */
2437 dwLen = 12;
2438 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2439 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2441 /* Second test case: Test the TLS1 pseudo random number function. */
2442 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2443 ok (result, "%08x\n", GetLastError());
2444 if (!result) return;
2446 /* Set the label and seed parameters for the random number function */
2447 data_blob.cbData = 36;
2448 data_blob.pbData = abHashedHandshakes;
2449 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2450 ok (result, "%08x\n", GetLastError());
2451 if (!result) return;
2453 data_blob.cbData = 15;
2454 data_blob.pbData = abClientFinished;
2455 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2456 ok (result, "%08x\n", GetLastError());
2457 if (!result) return;
2459 /* Generate some pseudo random bytes and check if they are correct. */
2460 dwLen = (DWORD)sizeof(abData);
2461 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2462 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2463 "%08x\n", GetLastError());
2465 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2466 * Hash some data with the HMAC. Compare results. */
2467 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2468 ok (result, "%08x\n", GetLastError());
2469 if (!result) return;
2471 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2472 ok (result, "%08x\n", GetLastError());
2473 if (!result) return;
2475 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2476 ok (result, "%08x\n", GetLastError());
2477 if (!result) return;
2479 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2480 ok (result, "%08x\n", GetLastError());
2481 if (!result) return;
2483 dwLen = (DWORD)sizeof(abMD5Hash);
2484 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2485 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2487 CryptDestroyHash(hHMAC);
2488 CryptDestroyHash(hTLS1PRF);
2489 CryptDestroyHash(hMasterHash);
2490 CryptDestroyKey(hServerWriteMACKey);
2491 CryptDestroyKey(hServerWriteKey);
2492 CryptDestroyKey(hRSAKey);
2493 CryptDestroyKey(hMasterSecret);
2494 CryptReleaseContext(hProv, 0);
2495 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2498 /* Test that a key can be used to encrypt data and exported, and that, when
2499 * the exported key is imported again, can be used to decrypt the original
2500 * data again.
2502 static void test_rsa_round_trip(void)
2504 static const char test_string[] = "Well this is a fine how-do-you-do.";
2505 HCRYPTPROV prov;
2506 HCRYPTKEY signKey, keyExchangeKey;
2507 BOOL result;
2508 BYTE data[256], *exportedKey;
2509 DWORD dataLen, keyLen;
2511 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2512 CRYPT_DELETEKEYSET);
2514 /* Generate a new key... */
2515 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2516 CRYPT_NEWKEYSET);
2517 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2518 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2519 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2520 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2521 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2522 /* encrypt some data with it... */
2523 memcpy(data, test_string, strlen(test_string) + 1);
2524 dataLen = strlen(test_string) + 1;
2525 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2526 sizeof(data));
2527 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2528 broken(GetLastError() == NTE_PERM /* NT4 */),
2529 "CryptEncrypt failed: %08x\n", GetLastError());
2530 /* export the key... */
2531 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2532 &keyLen);
2533 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2534 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2535 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2536 &keyLen);
2537 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2538 /* destroy the key... */
2539 CryptDestroyKey(keyExchangeKey);
2540 CryptDestroyKey(signKey);
2541 /* import the key again... */
2542 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2543 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2544 HeapFree(GetProcessHeap(), 0, exportedKey);
2545 /* and decrypt the data encrypted with the original key with the imported
2546 * key.
2548 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2549 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2550 broken(GetLastError() == NTE_PERM /* NT4 */),
2551 "CryptDecrypt failed: %08x\n", GetLastError());
2552 if (result)
2554 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2555 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2557 CryptDestroyKey(keyExchangeKey);
2558 CryptReleaseContext(prov, 0);
2560 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2561 CRYPT_DELETEKEYSET);
2564 static void test_enum_container(void)
2566 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2567 DWORD dwBufferLen;
2568 BOOL result, fFound = FALSE;
2570 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2571 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2572 SetLastError(0xdeadbeef);
2573 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2574 ok (result, "%08x\n", GetLastError());
2575 ok (dwBufferLen == MAX_PATH + 1 ||
2576 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2577 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2579 /* If the result fits into abContainerName dwBufferLen is left untouched */
2580 dwBufferLen = (DWORD)sizeof(abContainerName);
2581 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2582 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2584 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2585 do {
2586 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2587 dwBufferLen = (DWORD)sizeof(abContainerName);
2588 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2590 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2593 static BYTE signBlob[] = {
2594 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2595 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2596 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2597 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2598 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2599 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2600 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2601 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2602 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2603 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2604 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2605 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2606 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2607 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2608 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2609 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2610 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2611 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2612 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2613 0xb6,0x85,0x86,0x07 };
2615 static void test_null_provider(void)
2617 HCRYPTPROV prov;
2618 HCRYPTKEY key;
2619 BOOL result;
2620 DWORD keySpec, dataLen,dwParam;
2621 char szName[MAX_PATH];
2623 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2624 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2625 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2626 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2627 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2628 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2629 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2630 CRYPT_DELETEKEYSET);
2631 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2632 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2633 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2634 CRYPT_DELETEKEYSET);
2635 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2636 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2637 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2638 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2639 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2641 /* Delete the default container. */
2642 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2643 /* Once you've deleted the default container you can't open it as if it
2644 * already exists.
2646 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2647 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2648 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2649 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2650 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2651 CRYPT_VERIFYCONTEXT);
2652 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2653 if (!result) return;
2654 dataLen = sizeof(keySpec);
2655 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2656 if (result)
2657 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2658 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2659 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2660 * supported, you can't get the keys from this container.
2662 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2663 ok(!result && GetLastError() == NTE_NO_KEY,
2664 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2665 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2666 ok(!result && GetLastError() == NTE_NO_KEY,
2667 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2668 result = CryptReleaseContext(prov, 0);
2669 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2670 /* You can create a new default container. */
2671 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2672 CRYPT_NEWKEYSET);
2673 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2674 /* But you still can't get the keys (until one's been generated.) */
2675 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2676 ok(!result && GetLastError() == NTE_NO_KEY,
2677 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2678 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2679 ok(!result && GetLastError() == NTE_NO_KEY,
2680 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2681 CryptReleaseContext(prov, 0);
2682 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2684 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2685 CRYPT_DELETEKEYSET);
2686 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2687 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2688 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2689 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2690 CRYPT_VERIFYCONTEXT);
2691 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2692 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2693 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2694 CRYPT_NEWKEYSET);
2695 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2696 if (!result) return;
2697 /* Test provider parameters getter */
2698 dataLen = sizeof(dwParam);
2699 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2700 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2701 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2702 dataLen = sizeof(dwParam);
2703 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2704 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2705 "Expected 0, got 0x%08X\n",dwParam);
2706 dataLen = sizeof(dwParam);
2707 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2708 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2709 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2710 dataLen = sizeof(keySpec);
2711 SetLastError(0xdeadbeef);
2712 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2713 if (!result && GetLastError() == NTE_BAD_TYPE)
2714 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2715 else
2716 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2717 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2718 /* PP_CONTAINER parameter */
2719 dataLen = sizeof(szName);
2720 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2721 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2722 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2723 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2724 /* PP_UNIQUE_CONTAINER parameter */
2725 dataLen = sizeof(szName);
2726 SetLastError(0xdeadbeef);
2727 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2728 if (!result && GetLastError() == NTE_BAD_TYPE)
2730 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2732 else
2734 char container[MAX_PATH];
2736 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2737 uniquecontainer(container);
2738 todo_wine
2740 ok(dataLen == strlen(container)+1 ||
2741 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2742 "Expected a param length of 70, got %d\n", dataLen);
2743 ok(!strcmp(container, szName) ||
2744 broken(!strcmp(szName, szContainer)) /* WinME */,
2745 "Wrong container name : %s\n", szName);
2748 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2749 ok(!result && GetLastError() == NTE_NO_KEY,
2750 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2751 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2752 ok(!result && GetLastError() == NTE_NO_KEY,
2753 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2755 /* Importing a key exchange blob.. */
2756 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2757 0, 0, &key);
2758 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2759 CryptDestroyKey(key);
2760 /* allows access to the key exchange key.. */
2761 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2762 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2763 CryptDestroyKey(key);
2764 /* but not to the private key. */
2765 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2766 ok(!result && GetLastError() == NTE_NO_KEY,
2767 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2768 CryptReleaseContext(prov, 0);
2769 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2770 CRYPT_DELETEKEYSET);
2772 /* Whereas importing a sign blob.. */
2773 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2774 CRYPT_NEWKEYSET);
2775 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2776 if (!result) return;
2777 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2778 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2779 CryptDestroyKey(key);
2780 /* doesn't allow access to the key exchange key.. */
2781 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2782 ok(!result && GetLastError() == NTE_NO_KEY,
2783 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2784 /* but does to the private key. */
2785 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2786 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2787 CryptDestroyKey(key);
2788 CryptReleaseContext(prov, 0);
2790 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2791 CRYPT_DELETEKEYSET);
2793 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2794 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2795 CRYPT_NEWKEYSET);
2796 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2797 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2798 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2799 CryptDestroyKey(key);
2800 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2801 ok(!result, "expected CryptGetUserKey to fail\n");
2802 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2803 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2804 CryptDestroyKey(key);
2805 CryptReleaseContext(prov, 0);
2807 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2808 CRYPT_DELETEKEYSET);
2810 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2811 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2812 CRYPT_NEWKEYSET);
2813 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2814 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2815 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2816 CryptDestroyKey(key);
2817 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2818 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2819 CryptDestroyKey(key);
2820 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2821 ok(!result, "expected CryptGetUserKey to fail\n");
2822 CryptReleaseContext(prov, 0);
2824 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2825 CRYPT_DELETEKEYSET);
2827 /* test for the bug in accessing the user key in a container
2829 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2830 CRYPT_NEWKEYSET);
2831 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2832 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2833 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2834 CryptDestroyKey(key);
2835 CryptReleaseContext(prov,0);
2836 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2837 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2838 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2839 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2840 CryptDestroyKey(key);
2841 CryptReleaseContext(prov, 0);
2843 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2844 CRYPT_DELETEKEYSET);
2846 /* test the machine key set */
2847 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2848 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2849 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2850 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2851 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2852 CryptReleaseContext(prov, 0);
2853 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2854 CRYPT_MACHINE_KEYSET);
2855 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2856 CryptReleaseContext(prov,0);
2857 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2858 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2859 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2860 GetLastError());
2861 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2862 CRYPT_MACHINE_KEYSET);
2863 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2864 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2868 static void test_key_permissions(void)
2870 HCRYPTKEY hKey1, hKey2;
2871 DWORD dwVal, dwLen;
2872 BOOL result;
2874 /* Create keys that are exportable */
2875 if (!init_base_environment(CRYPT_EXPORTABLE))
2876 return;
2878 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2879 ok (result, "%08x\n", GetLastError());
2880 if (!result) return;
2882 dwVal = 0xdeadbeef;
2883 dwLen = sizeof(DWORD);
2884 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2885 ok(result, "%08x\n", GetLastError());
2886 ok(dwVal ==
2887 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2888 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2889 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2890 " got %08x\n", dwVal);
2892 /* The key exchange key's public key may be exported.. */
2893 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2894 ok(result, "%08x\n", GetLastError());
2895 /* and its private key may be too. */
2896 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2897 ok(result, "%08x\n", GetLastError());
2898 /* Turning off the key's export permissions is "allowed".. */
2899 dwVal &= ~CRYPT_EXPORT;
2900 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2901 ok(result ||
2902 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2903 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2904 "%08x\n", GetLastError());
2905 /* but it has no effect. */
2906 dwVal = 0xdeadbeef;
2907 dwLen = sizeof(DWORD);
2908 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2909 ok(result, "%08x\n", GetLastError());
2910 ok(dwVal ==
2911 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2912 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2913 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2914 " got %08x\n", dwVal);
2915 /* Thus, changing the export flag of the key doesn't affect whether the key
2916 * may be exported.
2918 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2919 ok(result, "%08x\n", GetLastError());
2921 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2922 ok (result, "%08x\n", GetLastError());
2924 /* A subsequent get of the same key, into a different handle, also doesn't
2925 * show that the permissions have been changed.
2927 dwVal = 0xdeadbeef;
2928 dwLen = sizeof(DWORD);
2929 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2930 ok(result, "%08x\n", GetLastError());
2931 ok(dwVal ==
2932 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2933 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2934 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2935 " got %08x\n", dwVal);
2937 CryptDestroyKey(hKey2);
2938 CryptDestroyKey(hKey1);
2940 clean_up_base_environment();
2943 static void test_key_initialization(void)
2945 DWORD dwLen;
2946 HCRYPTPROV prov1, prov2;
2947 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2948 BOOL result;
2949 static BYTE abSessionKey[148] = {
2950 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2951 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2952 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2953 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2954 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2955 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2956 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2957 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2958 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2959 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2960 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2961 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2962 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2963 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2964 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2965 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2966 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2967 0x04, 0x8c, 0x49, 0x92
2970 /* Like init_base_environment, but doesn't generate new keys, as they'll
2971 * be imported instead.
2973 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2975 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2976 CRYPT_NEWKEYSET);
2977 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2979 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2980 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2981 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2983 dwLen = (DWORD)sizeof(abSessionKey);
2984 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2985 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2987 /* Once the key has been imported, subsequently acquiring a context with
2988 * the same name will allow retrieving the key.
2990 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2991 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2992 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2993 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2994 if (result) CryptDestroyKey(hKey);
2995 CryptReleaseContext(prov2, 0);
2997 CryptDestroyKey(hSessionKey);
2998 CryptDestroyKey(hKeyExchangeKey);
2999 CryptReleaseContext(prov1, 0);
3000 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
3001 CRYPT_DELETEKEYSET);
3004 START_TEST(rsaenh)
3006 if (!init_base_environment(0))
3007 return;
3008 test_prov();
3009 test_gen_random();
3010 test_hashes();
3011 test_rc4();
3012 test_rc2();
3013 test_des();
3014 test_3des112();
3015 test_3des();
3016 test_hmac();
3017 test_mac();
3018 test_block_cipher_modes();
3019 test_import_private();
3020 test_verify_signature();
3021 test_rsa_encrypt();
3022 test_import_export();
3023 test_import_hmac();
3024 test_enum_container();
3025 clean_up_base_environment();
3026 test_key_permissions();
3027 test_key_initialization();
3028 test_schannel_provider();
3029 test_null_provider();
3030 test_rsa_round_trip();
3031 if (!init_aes_environment())
3032 return;
3033 test_aes(128);
3034 test_aes(192);
3035 test_aes(256);
3036 test_sha2();
3037 clean_up_aes_environment();