Sync advapi32, comctl32, crypt32, cryptui, cryptnet, fusion, gdi32, gdiplus, hlink...
[reactos.git] / rostests / winetests / rsaenh / rsaenh.c
1 /*
2 * Unit tests for rsaenh functions
3 *
4 * Copyright (c) 2004 Michael Jung
5 * Copyright (c) 2006 Juan Lang
6 * Copyright (c) 2007 Vijay Kiran Kamuju
7 *
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.
12 *
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.
17 *
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
21 */
22
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"
31
32 static HCRYPTPROV hProv;
33 static const char szContainer[] = "winetest";
34 static const char szProvider[] = MS_ENHANCED_PROV_A;
35
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;
43
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}
57 };
58
59 /*
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
64 *
65 */
66 static void uniquecontainer(char *unique)
67 {
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;
76
77 /* Get the MachineGUID */
78 ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szCryptography, 0, KEY_READ | KEY_WOW64_64KEY, &hkey);
79 if (ret == ERROR_ACCESS_DENIED)
80 {
81 /* Windows 2000 can't handle KEY_WOW64_64KEY */
82 RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
83 }
84 RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
85 RegCloseKey(hkey);
86
87 lstrcpy(unique, szContainer_md5);
88 lstrcat(unique, "_");
89 lstrcat(unique, guid);
90 }
91
92 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
93 {
94 size_t i;
95 printf("%s: ",heading);
96 for(i=0;i<cb;i++)
97 printf("0x%02x,",pb[i]);
98 putchar('\n');
99 }
100
101 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
102
103 /*
104 static void trace_hex(BYTE *pbData, DWORD dwLen) {
105 char szTemp[256];
106 DWORD i, j;
107
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);
113 }
114 for (j=0; i<dwLen; j++,i++) {
115 sprintf(szTemp+6*j, "0x%02x,\n", pbData[i]);
116 }
117 trace(szTemp);
118 }
119 */
120
121 static int init_base_environment(DWORD dwKeyFlags)
122 {
123 HCRYPTKEY hKey;
124 BOOL result;
125
126 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
127
128 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
129
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());
134
135 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
136 {
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)
142 {
143 win_skip("RSA full provider not available\n");
144 return 0;
145 }
146 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
147 CRYPT_NEWKEYSET);
148 ok(result, "%08x\n", GetLastError());
149 if (!result)
150 {
151 win_skip("Couldn't create crypto provider\n");
152 return 0;
153 }
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);
160 }
161 return 1;
162 }
163
164 static void clean_up_base_environment(void)
165 {
166 BOOL result;
167
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());
172
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());
177
178 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
179 }
180
181 static int init_aes_environment(void)
182 {
183 HCRYPTKEY hKey;
184 BOOL result;
185
186 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
187
188 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
189
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. */
194
195 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
196 if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
197 {
198 win_skip("RSA_AES provider not supported\n");
199 return 0;
200 }
201 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
202
203 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
204 {
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);
217 }
218 return 1;
219 }
220
221 static void clean_up_aes_environment(void)
222 {
223 BOOL result;
224
225 result = CryptReleaseContext(hProv, 1);
226 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
227
228 CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
229 }
230
231 static void test_prov(void)
232 {
233 BOOL result;
234 DWORD dwLen, dwInc;
235
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);
243
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);
251 }
252
253 static void test_gen_random(void)
254 {
255 BOOL result;
256 BYTE rnd1[16], rnd2[16];
257
258 memset(rnd1, 0, sizeof(rnd1));
259 memset(rnd2, 0, sizeof(rnd2));
260
261 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
262 if (!result && GetLastError() == NTE_FAIL) {
263 /* rsaenh compiled without OpenSSL */
264 return;
265 }
266
267 ok(result, "%08x\n", GetLastError());
268
269 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
270 ok(result, "%08x\n", GetLastError());
271
272 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
273 }
274
275 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
276 {
277 HCRYPTHASH hHash;
278 BOOL result;
279 unsigned char pbData[2000];
280 int i;
281
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;
289 }
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;
302 }
303
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
380 };
381
382 static void test_hashes(void)
383 {
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;
419
420 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
421
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());
430
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);
434
435 len = 16;
436 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
437 ok(result, "%08x\n", GetLastError());
438
439 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
440
441 result = CryptDestroyHash(hHash);
442 ok(result, "%08x\n", GetLastError());
443 }
444
445 /* MD4 Hashing */
446 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
447 ok(result, "%08x\n", GetLastError());
448
449 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
450 ok(result, "%08x\n", GetLastError());
451
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);
455
456 len = 16;
457 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
458 ok(result, "%08x\n", GetLastError());
459
460 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
461
462 result = CryptDestroyHash(hHash);
463 ok(result, "%08x\n", GetLastError());
464
465 /* MD5 Hashing */
466 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
467 ok(result, "%08x\n", GetLastError());
468
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);
472
473 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
474 ok(result, "%08x\n", GetLastError());
475
476 len = 16;
477 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
478 ok(result, "%08x\n", GetLastError());
479
480 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
481
482 result = CryptDestroyHash(hHash);
483 ok(result, "%08x\n", GetLastError());
484
485 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
486 ok(result, "%08x\n", GetLastError());
487
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());
492
493 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
494
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());
498
499 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
500
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());
508
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());
512
513 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
514
515 result = CryptDestroyHash(hHash);
516 ok(result, "%08x\n", GetLastError());
517
518 /* SHA1 Hashing */
519 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
520 ok(result, "%08x\n", GetLastError());
521
522 result = CryptHashData(hHash, pbData, 5, 0);
523 ok(result, "%08x\n", GetLastError());
524
525 if(pCryptDuplicateHash) {
526 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
527 ok(result, "%08x\n", GetLastError());
528
529 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
530 ok(result, "%08x\n", GetLastError());
531
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);
535
536 len = 20;
537 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
538 ok(result, "%08x\n", GetLastError());
539
540 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
541
542 result = CryptDestroyHash(hHashClone);
543 ok(result, "%08x\n", GetLastError());
544 }
545
546 result = CryptDestroyHash(hHash);
547 ok(result, "%08x\n", GetLastError());
548
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());
559
560 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
561 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
562
563 result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash);
564 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
565
566 /* release provider before using the hash */
567 result = CryptReleaseContext(prov, 0);
568 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
569
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);
575
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);
581
582 if (!pCryptDuplicateHash)
583 {
584 win_skip("CryptDuplicateHash is not available\n");
585 return;
586 }
587
588 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
589 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
590
591 result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
592 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
593
594 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
595 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
596
597 result = pCryptDuplicateHash(hHash, NULL, 0, &hHashClone);
598 ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
599
600 len = 20;
601 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
602 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
603
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());
607
608 result = CryptDestroyHash(hHash);
609 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
610
611 result = CryptDestroyHash(hHashClone);
612 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
613
614 result = CryptReleaseContext(prov, 0);
615 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
616
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());
620
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))
660 {
661 printBytes("expected", signed_ssl3_shamd5_hash,
662 sizeof(signed_ssl3_shamd5_hash));
663 printBytes("got", pbSigValue, len);
664 }
665 result = CryptDestroyHash(hHash);
666 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
667 result = CryptReleaseContext(prov, 0);
668 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
669 }
670
671 static void test_block_cipher_modes(void)
672 {
673 static const BYTE plain[23] = {
674 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
675 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
676 static const BYTE ecb[24] = {
677 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
678 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
679 static const BYTE cbc[24] = {
680 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
681 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
682 static const BYTE cfb[24] = {
683 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
684 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
685 HCRYPTKEY hKey;
686 BOOL result;
687 BYTE abData[24];
688 DWORD dwMode, dwLen;
689
690 result = derive_key(CALG_RC2, &hKey, 40);
691 if (!result) return;
692
693 memcpy(abData, plain, sizeof(plain));
694
695 dwMode = CRYPT_MODE_ECB;
696 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
697 ok(result, "%08x\n", GetLastError());
698
699 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
700 ok(result, "%08x\n", GetLastError());
701 ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
702
703 dwLen = 23;
704 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
705 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
706 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
707
708 SetLastError(ERROR_SUCCESS);
709 dwLen = 23;
710 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
711 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
712 "%08x, dwLen: %d\n", GetLastError(), dwLen);
713
714 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
715 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
716 "%08x, dwLen: %d\n", GetLastError(), dwLen);
717
718 dwMode = CRYPT_MODE_CBC;
719 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
720 ok(result, "%08x\n", GetLastError());
721
722 dwLen = 23;
723 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
724 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
725 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
726
727 dwLen = 23;
728 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
729 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
730 "%08x, dwLen: %d\n", GetLastError(), dwLen);
731
732 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
733 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
734 "%08x, dwLen: %d\n", GetLastError(), dwLen);
735
736 dwMode = CRYPT_MODE_CFB;
737 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
738 ok(result, "%08x\n", GetLastError());
739
740 dwLen = 16;
741 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
742 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
743
744 dwLen = 7;
745 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
746 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
747 "%08x, dwLen: %d\n", GetLastError(), dwLen);
748
749 dwLen = 8;
750 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
751 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
752
753 dwLen = 16;
754 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
755 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
756 "%08x, dwLen: %d\n", GetLastError(), dwLen);
757
758 dwMode = CRYPT_MODE_OFB;
759 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
760 ok(result, "%08x\n", GetLastError());
761
762 dwLen = 23;
763 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
764 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
765
766 CryptDestroyKey(hKey);
767 }
768
769 static void test_3des112(void)
770 {
771 HCRYPTKEY hKey;
772 BOOL result;
773 DWORD dwLen;
774 unsigned char pbData[16];
775 int i;
776
777 result = derive_key(CALG_3DES_112, &hKey, 0);
778 if (!result) {
779 /* rsaenh compiled without OpenSSL */
780 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
781 return;
782 }
783
784 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
785
786 dwLen = 13;
787 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
788 ok(result, "%08x\n", GetLastError());
789
790 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
791 ok(result, "%08x\n", GetLastError());
792
793 for (i=0; i<4; i++)
794 {
795 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
796
797 dwLen = cTestData[i].enclen;
798 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
799 ok(result, "%08x\n", GetLastError());
800 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
801
802 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
803 ok(result, "%08x\n", GetLastError());
804 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
805 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
806 if((dwLen != cTestData[i].enclen) ||
807 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
808 {
809 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
810 printBytes("got",pbData,dwLen);
811 }
812 }
813 result = CryptDestroyKey(hKey);
814 ok(result, "%08x\n", GetLastError());
815 }
816
817 static void test_des(void)
818 {
819 HCRYPTKEY hKey;
820 BOOL result;
821 DWORD dwLen, dwMode;
822 unsigned char pbData[16];
823 int i;
824
825 result = derive_key(CALG_DES, &hKey, 56);
826 if (!result) {
827 /* rsaenh compiled without OpenSSL */
828 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
829 return;
830 }
831
832 dwMode = CRYPT_MODE_ECB;
833 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
834 ok(result, "%08x\n", GetLastError());
835
836 dwLen = sizeof(DWORD);
837 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
838 ok(result, "%08x\n", GetLastError());
839
840 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
841
842 dwLen = 13;
843 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
844 ok(result, "%08x\n", GetLastError());
845
846 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
847 ok(result, "%08x\n", GetLastError());
848
849 for (i=0; i<4; i++)
850 {
851 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
852
853 dwLen = cTestData[i].enclen;
854 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
855 ok(result, "%08x\n", GetLastError());
856 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
857
858 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
859 ok(result, "%08x\n", GetLastError());
860 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
861 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
862 if((dwLen != cTestData[i].enclen) ||
863 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
864 {
865 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
866 printBytes("got",pbData,dwLen);
867 }
868 }
869
870 result = CryptDestroyKey(hKey);
871 ok(result, "%08x\n", GetLastError());
872 }
873
874 static void test_3des(void)
875 {
876 HCRYPTKEY hKey;
877 BOOL result;
878 DWORD dwLen;
879 unsigned char pbData[16];
880 static const BYTE des3[16] = {
881 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
882 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
883 int i;
884
885 result = derive_key(CALG_3DES, &hKey, 0);
886 if (!result) return;
887
888 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
889
890 dwLen = 13;
891 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
892 ok(result, "%08x\n", GetLastError());
893
894 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
895
896 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
897 ok(result, "%08x\n", GetLastError());
898
899 for (i=0; i<4; i++)
900 {
901 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
902
903 dwLen = cTestData[i].enclen;
904 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
905 ok(result, "%08x\n", GetLastError());
906 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
907
908 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
909 ok(result, "%08x\n", GetLastError());
910 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
911 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
912 if((dwLen != cTestData[i].enclen) ||
913 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
914 {
915 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
916 printBytes("got",pbData,dwLen);
917 }
918 }
919 result = CryptDestroyKey(hKey);
920 ok(result, "%08x\n", GetLastError());
921 }
922
923 static void test_aes(int keylen)
924 {
925 HCRYPTKEY hKey;
926 BOOL result;
927 DWORD dwLen;
928 unsigned char pbData[16];
929 int i;
930
931 switch (keylen)
932 {
933 case 256:
934 result = derive_key(CALG_AES_256, &hKey, 0);
935 break;
936 case 192:
937 result = derive_key(CALG_AES_192, &hKey, 0);
938 break;
939 default:
940 case 128:
941 result = derive_key(CALG_AES_128, &hKey, 0);
942 break;
943 }
944 if (!result) return;
945
946 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
947
948 /* AES provider doesn't support salt */
949 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
950 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == ERROR_NO_TOKEN /* Win7 */),
951 "expected NTE_BAD_KEY or ERROR_NO_TOKEN, got %08x\n", GetLastError());
952
953 dwLen = 13;
954 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
955 ok(result, "%08x\n", GetLastError());
956
957 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
958 ok(result, "%08x\n", GetLastError());
959
960 for (i=0; i<4; i++)
961 {
962 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
963
964 dwLen = cTestData[i].enclen;
965 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
966 ok(result, "%08x\n", GetLastError());
967 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
968
969 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
970 ok(result, "%08x\n", GetLastError());
971 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
972 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
973 if((dwLen != cTestData[i].enclen) ||
974 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
975 {
976 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
977 printBytes("got",pbData,dwLen);
978 }
979 }
980 result = CryptDestroyKey(hKey);
981 ok(result, "%08x\n", GetLastError());
982 }
983
984 static void test_sha2(void)
985 {
986 static const unsigned char sha256hash[32] = {
987 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
988 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
989 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
990 0x1a, 0x08
991 };
992 static const unsigned char sha384hash[48] = {
993 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
994 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
995 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
996 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
997 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
998 };
999 static const unsigned char sha512hash[64] = {
1000 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1001 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1002 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1003 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1004 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1005 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1006 0xb7, 0xf4, 0x81, 0xd4
1007 };
1008 unsigned char pbData[2048];
1009 BOOL result;
1010 HCRYPTHASH hHash;
1011 BYTE pbHashValue[64];
1012 DWORD hashlen, len;
1013 int i;
1014
1015 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1016
1017 /* SHA-256 hash */
1018 SetLastError(0xdeadbeef);
1019 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1020 if (!result && GetLastError() == NTE_BAD_ALGID) {
1021 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1022 return;
1023 }
1024 ok(result, "%08x\n", GetLastError());
1025 if (result) {
1026 len = sizeof(DWORD);
1027 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1028 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1029
1030 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1031 ok(result, "%08x\n", GetLastError());
1032
1033 len = 32;
1034 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1035 ok(result, "%08x\n", GetLastError());
1036
1037 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1038
1039 result = CryptDestroyHash(hHash);
1040 ok(result, "%08x\n", GetLastError());
1041 }
1042
1043 /* SHA-384 hash */
1044 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1045 ok(result, "%08x\n", GetLastError());
1046 if (result) {
1047 len = sizeof(DWORD);
1048 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1049 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1050
1051 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1052 ok(result, "%08x\n", GetLastError());
1053
1054 len = 48;
1055 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1056 ok(result, "%08x\n", GetLastError());
1057
1058 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1059
1060 result = CryptDestroyHash(hHash);
1061 ok(result, "%08x\n", GetLastError());
1062 }
1063
1064 /* SHA-512 hash */
1065 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1066 ok(result, "%08x\n", GetLastError());
1067 if (result) {
1068 len = sizeof(DWORD);
1069 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1070 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1071
1072 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1073 ok(result, "%08x\n", GetLastError());
1074
1075 len = 64;
1076 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1077 ok(result, "%08x\n", GetLastError());
1078
1079 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1080
1081 result = CryptDestroyHash(hHash);
1082 ok(result, "%08x\n", GetLastError());
1083 }
1084 }
1085
1086 static void test_rc2(void)
1087 {
1088 static const BYTE rc2_40_encrypted[16] = {
1089 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1090 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1091 static const BYTE rc2_128_encrypted[] = {
1092 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
1093 0xb6,0x66 };
1094 HCRYPTHASH hHash;
1095 HCRYPTKEY hKey;
1096 BOOL result;
1097 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
1098 BYTE *pbTemp;
1099 unsigned char pbData[2000], pbHashValue[16];
1100 int i;
1101
1102 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1103
1104 /* MD2 Hashing */
1105 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1106 if (!result) {
1107 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1108 } else {
1109 CRYPT_INTEGER_BLOB salt;
1110
1111 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1112 ok(result, "%08x\n", GetLastError());
1113
1114 dwLen = 16;
1115 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1116 ok(result, "%08x\n", GetLastError());
1117
1118 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1119 ok(result, "%08x\n", GetLastError());
1120
1121 dwLen = sizeof(DWORD);
1122 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1123 ok(result, "%08x\n", GetLastError());
1124
1125 dwMode = CRYPT_MODE_CBC;
1126 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1127 ok(result, "%08x\n", GetLastError());
1128
1129 dwLen = sizeof(DWORD);
1130 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1131 ok(result, "%08x\n", GetLastError());
1132
1133 dwModeBits = 0xdeadbeef;
1134 dwLen = sizeof(DWORD);
1135 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1136 ok(result, "%08x\n", GetLastError());
1137 ok(dwModeBits ==
1138 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1139 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
1140 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1141 " got %08x\n", dwModeBits);
1142
1143 dwLen = sizeof(DWORD);
1144 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1145 ok(result, "%08x\n", GetLastError());
1146
1147 dwLen = sizeof(DWORD);
1148 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1149 ok(result, "%08x\n", GetLastError());
1150
1151 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1152 ok(result, "%08x\n", GetLastError());
1153 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1154 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1155 HeapFree(GetProcessHeap(), 0, pbTemp);
1156
1157 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1158 ok(result, "%08x\n", GetLastError());
1159 /* The default salt length is always 11... */
1160 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1161 /* and the default salt is always empty. */
1162 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1163 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1164 for (i=0; i<dwLen; i++)
1165 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1166 HeapFree(GetProcessHeap(), 0, pbTemp);
1167
1168 dwLen = sizeof(DWORD);
1169 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1170
1171 result = CryptDestroyHash(hHash);
1172 ok(result, "%08x\n", GetLastError());
1173
1174 dwDataLen = 13;
1175 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1176 ok(result, "%08x\n", GetLastError());
1177
1178 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1179
1180 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1181 ok(result, "%08x\n", GetLastError());
1182 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1183 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1184 HeapFree(GetProcessHeap(), 0, pbTemp);
1185
1186 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1187 ok(result, "%08x\n", GetLastError());
1188
1189 /* Setting the salt also succeeds... */
1190 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1191 ok(result, "setting salt failed: %08x\n", GetLastError());
1192 /* but the resulting salt length is now zero? */
1193 dwLen = 0;
1194 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1195 ok(result, "%08x\n", GetLastError());
1196 ok(dwLen == 0 ||
1197 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1198 "unexpected salt length %d\n", dwLen);
1199 /* What sizes salt can I set? */
1200 salt.pbData = pbData;
1201 for (i=0; i<24; i++)
1202 {
1203 salt.cbData = i;
1204 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1205 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1206 /* The returned salt length is the same as the set salt length */
1207 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1208 ok(result, "%08x\n", GetLastError());
1209 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1210 }
1211 salt.cbData = 25;
1212 SetLastError(0xdeadbeef);
1213 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1214 ok(!result ||
1215 broken(result), /* Win9x, WinMe, NT4, W2K */
1216 "%08x\n", GetLastError());
1217
1218 result = CryptDestroyKey(hKey);
1219 ok(result, "%08x\n", GetLastError());
1220 }
1221
1222 /* Again, but test setting the effective key len */
1223 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1224
1225 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1226 if (!result) {
1227 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1228 } else {
1229 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1230 ok(result, "%08x\n", GetLastError());
1231
1232 dwLen = 16;
1233 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1234 ok(result, "%08x\n", GetLastError());
1235
1236 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1237 ok(result, "%08x\n", GetLastError());
1238
1239 SetLastError(0xdeadbeef);
1240 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1241 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1242 dwKeyLen = 0;
1243 SetLastError(0xdeadbeef);
1244 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1245 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1246 dwKeyLen = 1025;
1247 SetLastError(0xdeadbeef);
1248 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1249
1250 dwLen = sizeof(dwKeyLen);
1251 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1252 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1253 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1254 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1255
1256 dwKeyLen = 128;
1257 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1258 ok(result, "%d\n", GetLastError());
1259
1260 dwLen = sizeof(dwKeyLen);
1261 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1262 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1263 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1264 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1265
1266 result = CryptDestroyHash(hHash);
1267 ok(result, "%08x\n", GetLastError());
1268
1269 dwDataLen = 13;
1270 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1271 ok(result, "%08x\n", GetLastError());
1272
1273 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1274 "RC2 encryption failed!\n");
1275
1276 /* Oddly enough this succeeds, though it should have no effect */
1277 dwKeyLen = 40;
1278 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1279 ok(result, "%d\n", GetLastError());
1280
1281 result = CryptDestroyKey(hKey);
1282 ok(result, "%08x\n", GetLastError());
1283 }
1284 }
1285
1286 static void test_rc4(void)
1287 {
1288 static const BYTE rc4[16] = {
1289 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1290 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1291 BOOL result;
1292 HCRYPTHASH hHash;
1293 HCRYPTKEY hKey;
1294 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1295 unsigned char pbData[2000], *pbTemp;
1296 unsigned char pszBuffer[256];
1297 int i;
1298
1299 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1300
1301 /* MD2 Hashing */
1302 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1303 if (!result) {
1304 /* rsaenh compiled without OpenSSL */
1305 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1306 } else {
1307 CRYPT_INTEGER_BLOB salt;
1308
1309 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1310 ok(result, "%08x\n", GetLastError());
1311
1312 dwLen = 16;
1313 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1314 ok(result, "%08x\n", GetLastError());
1315
1316 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1317 ok(result, "%08x\n", GetLastError());
1318
1319 dwLen = sizeof(DWORD);
1320 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1321 ok(result, "%08x\n", GetLastError());
1322
1323 dwLen = sizeof(DWORD);
1324 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1325 ok(result, "%08x\n", GetLastError());
1326
1327 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1328 ok(result, "%08x\n", GetLastError());
1329 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1330 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1331 HeapFree(GetProcessHeap(), 0, pbTemp);
1332
1333 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1334 ok(result, "%08x\n", GetLastError());
1335 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1336 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1337 HeapFree(GetProcessHeap(), 0, pbTemp);
1338
1339 dwLen = sizeof(DWORD);
1340 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1341
1342 result = CryptDestroyHash(hHash);
1343 ok(result, "%08x\n", GetLastError());
1344
1345 dwDataLen = 16;
1346 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1347 ok(result, "%08x\n", GetLastError());
1348 dwDataLen = 16;
1349 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1350 ok(result, "%08x\n", GetLastError());
1351
1352 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1353
1354 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1355 ok(result, "%08x\n", GetLastError());
1356
1357 /* Setting the salt also succeeds... */
1358 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1359 ok(result, "setting salt failed: %08x\n", GetLastError());
1360 /* but the resulting salt length is now zero? */
1361 dwLen = 0;
1362 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1363 ok(result, "%08x\n", GetLastError());
1364 ok(dwLen == 0 ||
1365 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1366 "unexpected salt length %d\n", dwLen);
1367 /* What sizes salt can I set? */
1368 salt.pbData = pbData;
1369 for (i=0; i<24; i++)
1370 {
1371 salt.cbData = i;
1372 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1373 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1374 /* The returned salt length is the same as the set salt length */
1375 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1376 ok(result, "%08x\n", GetLastError());
1377 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1378 }
1379 salt.cbData = 25;
1380 SetLastError(0xdeadbeef);
1381 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1382 ok(!result ||
1383 broken(result), /* Win9x, WinMe, NT4, W2K */
1384 "%08x\n", GetLastError());
1385
1386 result = CryptDestroyKey(hKey);
1387 ok(result, "%08x\n", GetLastError());
1388 }
1389 }
1390
1391 static void test_hmac(void) {
1392 HCRYPTKEY hKey;
1393 HCRYPTHASH hHash;
1394 BOOL result;
1395 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1396 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1397 DWORD dwLen;
1398 BYTE abData[256];
1399 static const BYTE hmac[16] = {
1400 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1401 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1402 int i;
1403
1404 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1405
1406 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1407
1408 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1409 ok(result, "%08x\n", GetLastError());
1410 if (!result) return;
1411
1412 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1413 ok(result, "%08x\n", GetLastError());
1414
1415 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1416 ok(result, "%08x\n", GetLastError());
1417
1418 dwLen = sizeof(abData)/sizeof(BYTE);
1419 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1420 ok(result, "%08x\n", GetLastError());
1421
1422 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1423
1424 result = CryptDestroyHash(hHash);
1425 ok(result, "%08x\n", GetLastError());
1426
1427 result = CryptDestroyKey(hKey);
1428 ok(result, "%08x\n", GetLastError());
1429
1430 /* Provoke errors */
1431 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1432 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1433 }
1434
1435 static void test_mac(void) {
1436 HCRYPTKEY hKey;
1437 HCRYPTHASH hHash;
1438 BOOL result;
1439 DWORD dwLen;
1440 BYTE abData[256], abEnc[264];
1441 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1442 int i;
1443
1444 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1445 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1446
1447 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1448
1449 dwLen = 256;
1450 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1451 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1452
1453 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1454 ok(result, "%08x\n", GetLastError());
1455 if (!result) return;
1456
1457 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1458 ok(result, "%08x\n", GetLastError());
1459
1460 dwLen = sizeof(abData)/sizeof(BYTE);
1461 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1462 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1463
1464 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1465
1466 result = CryptDestroyHash(hHash);
1467 ok(result, "%08x\n", GetLastError());
1468
1469 result = CryptDestroyKey(hKey);
1470 ok(result, "%08x\n", GetLastError());
1471
1472 /* Provoke errors */
1473 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1474
1475 SetLastError(0xdeadbeef);
1476 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1477 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1478 broken(result), /* Win9x, WinMe, NT4, W2K */
1479 "%08x\n", GetLastError());
1480
1481 result = CryptDestroyKey(hKey);
1482 ok(result, "%08x\n", GetLastError());
1483 }
1484
1485 static void test_import_private(void)
1486 {
1487 DWORD dwLen, dwVal;
1488 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1489 BOOL result;
1490 static BYTE abSessionKey[148] = {
1491 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1492 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1493 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1494 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1495 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1496 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1497 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1498 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1499 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1500 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1501 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1502 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1503 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1504 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1505 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1506 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1507 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1508 0x04, 0x8c, 0x49, 0x92
1509 };
1510 static BYTE abEncryptedMessage[12] = {
1511 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1512 0x1c, 0xfd, 0xde, 0x71
1513 };
1514
1515 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1516 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1517 if (!result) {
1518 /* rsaenh compiled without OpenSSL */
1519 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1520 return;
1521 }
1522
1523 dwLen = (DWORD)sizeof(abSessionKey);
1524 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1525 ok(result, "%08x\n", GetLastError());
1526 if (!result) return;
1527
1528 dwVal = 0xdeadbeef;
1529 dwLen = sizeof(DWORD);
1530 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1531 ok(result, "%08x\n", GetLastError());
1532 ok(dwVal ==
1533 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1534 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1535 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1536 " got %08x\n", dwVal);
1537
1538 dwLen = (DWORD)sizeof(abEncryptedMessage);
1539 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1540 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1541 "%08x, len: %d\n", GetLastError(), dwLen);
1542 CryptDestroyKey(hSessionKey);
1543
1544 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1545
1546 dwLen = (DWORD)sizeof(abSessionKey);
1547 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1548 ok(result, "%08x\n", GetLastError());
1549 CryptDestroyKey(hSessionKey);
1550 if (!result) return;
1551
1552 dwLen = (DWORD)sizeof(abSessionKey);
1553 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1554 ok(result, "%08x\n", GetLastError());
1555 if (!result) return;
1556
1557 CryptDestroyKey(hSessionKey);
1558 CryptDestroyKey(hKeyExchangeKey);
1559 }
1560
1561 static void test_verify_signature(void) {
1562 HCRYPTHASH hHash;
1563 HCRYPTKEY hPubSignKey;
1564 BYTE abData[] = "Wine rocks!";
1565 BOOL result;
1566 BYTE abPubKey[148] = {
1567 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1568 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1569 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1570 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1571 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1572 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1573 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1574 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1575 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1576 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1577 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1578 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1579 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1580 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1581 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1582 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1583 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1584 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1585 0xe1, 0x21, 0x50, 0xac
1586 };
1587 /* md2 with hash oid */
1588 BYTE abSignatureMD2[128] = {
1589 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1590 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1591 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1592 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1593 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1594 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1595 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1596 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1597 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1598 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1599 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1600 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1601 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1602 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1603 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1604 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1605 };
1606 /* md2 without hash oid */
1607 BYTE abSignatureMD2NoOID[128] = {
1608 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1609 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1610 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1611 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1612 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1613 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1614 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1615 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1616 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1617 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1618 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1619 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1620 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1621 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1622 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1623 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1624 };
1625 /* md4 with hash oid */
1626 BYTE abSignatureMD4[128] = {
1627 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1628 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1629 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1630 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1631 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1632 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1633 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1634 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1635 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1636 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1637 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1638 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1639 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1640 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1641 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1642 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1643 };
1644 /* md4 without hash oid */
1645 BYTE abSignatureMD4NoOID[128] = {
1646 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1647 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1648 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1649 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1650 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1651 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1652 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1653 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1654 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1655 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1656 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1657 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1658 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1659 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1660 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1661 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1662 };
1663 /* md5 with hash oid */
1664 BYTE abSignatureMD5[128] = {
1665 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1666 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1667 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1668 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1669 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1670 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1671 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1672 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1673 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1674 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1675 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1676 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1677 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1678 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1679 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1680 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1681 };
1682 /* md5 without hash oid */
1683 BYTE abSignatureMD5NoOID[128] = {
1684 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1685 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1686 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1687 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1688 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1689 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1690 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1691 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1692 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1693 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1694 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1695 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1696 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1697 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1698 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1699 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1700 };
1701 /* sha with hash oid */
1702 BYTE abSignatureSHA[128] = {
1703 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1704 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1705 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1706 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1707 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1708 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1709 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1710 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1711 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1712 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1713 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1714 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1715 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1716 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1717 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1718 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1719 };
1720 /* sha without hash oid */
1721 BYTE abSignatureSHANoOID[128] = {
1722 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1723 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1724 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1725 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1726 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1727 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1728 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1729 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1730 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1731 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1732 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1733 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1734 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1735 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1736 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1737 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1738 };
1739
1740 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1741 ok(result, "%08x\n", GetLastError());
1742 if (!result) return;
1743
1744 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1745 ok(result, "%08x\n", GetLastError());
1746 if (!result) return;
1747
1748 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1749 ok(result, "%08x\n", GetLastError());
1750 if (!result) return;
1751
1752 /*check that a NULL pointer signature is correctly handled*/
1753 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1754 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1755 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1756 if (result) return;
1757
1758 /* check that we get a bad signature error when the signature is too short*/
1759 SetLastError(0xdeadbeef);
1760 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1761 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1762 broken(result), /* Win9x, WinMe, NT4 */
1763 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1764
1765 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1766 ok(result, "%08x\n", GetLastError());
1767 if (!result) return;
1768
1769 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1770 ok(result, "%08x\n", GetLastError());
1771 if (!result) return;
1772
1773 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1774 * the OID at all. */
1775 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1776 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1777 if (result) return;*/
1778
1779 CryptDestroyHash(hHash);
1780
1781 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1782 ok(result, "%08x\n", GetLastError());
1783 if (!result) return;
1784
1785 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1786 ok(result, "%08x\n", GetLastError());
1787 if (!result) return;
1788
1789 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1790 ok(result, "%08x\n", GetLastError());
1791 if (!result) return;
1792
1793 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1794 ok(result, "%08x\n", GetLastError());
1795 if (!result) return;
1796
1797 CryptDestroyHash(hHash);
1798
1799 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1800 ok(result, "%08x\n", GetLastError());
1801 if (!result) return;
1802
1803 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1804 ok(result, "%08x\n", GetLastError());
1805 if (!result) return;
1806
1807 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1808 ok(result, "%08x\n", GetLastError());
1809 if (!result) return;
1810
1811 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1812 ok(result, "%08x\n", GetLastError());
1813 if (!result) return;
1814
1815 CryptDestroyHash(hHash);
1816
1817 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1818 ok(result, "%08x\n", GetLastError());
1819 if (!result) return;
1820
1821 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1822 ok(result, "%08x\n", GetLastError());
1823 if (!result) return;
1824
1825 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1826 ok(result, "%08x\n", GetLastError());
1827 if (!result) return;
1828
1829 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1830 ok(result, "%08x\n", GetLastError());
1831 if (!result) return;
1832
1833 CryptDestroyHash(hHash);
1834 CryptDestroyKey(hPubSignKey);
1835 }
1836
1837 static void test_rsa_encrypt(void)
1838 {
1839 HCRYPTKEY hRSAKey;
1840 BYTE abData[2048] = "Wine rocks!";
1841 BOOL result;
1842 DWORD dwVal, dwLen;
1843
1844 /* It is allowed to use the key exchange key for encryption/decryption */
1845 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1846 ok (result, "%08x\n", GetLastError());
1847 if (!result) return;
1848
1849 dwLen = 12;
1850 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1851 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1852 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1853 dwLen = 12;
1854 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1855 ok (result, "%08x\n", GetLastError());
1856 if (!result) return;
1857
1858 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1859 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1860
1861 dwVal = 0xdeadbeef;
1862 dwLen = sizeof(DWORD);
1863 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1864 ok(result, "%08x\n", GetLastError());
1865 ok(dwVal ==
1866 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1867 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1868 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1869 " got %08x\n", dwVal);
1870
1871 /* An RSA key doesn't support salt */
1872 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1873 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
1874 "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
1875
1876 /* The key exchange key's public key may be exported.. */
1877 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1878 ok(result, "%08x\n", GetLastError());
1879 /* but its private key may not be. */
1880 SetLastError(0xdeadbeef);
1881 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1882 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1883 broken(result), /* Win9x/NT4 */
1884 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1885 /* Setting the permissions of the key exchange key isn't allowed, either. */
1886 dwVal |= CRYPT_EXPORT;
1887 SetLastError(0xdeadbeef);
1888 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1889 ok(!result &&
1890 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1891 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1892
1893 CryptDestroyKey(hRSAKey);
1894
1895 /* It is not allowed to use the signature key for encryption/decryption */
1896 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1897 ok (result, "%08x\n", GetLastError());
1898 if (!result) return;
1899
1900 dwVal = 0xdeadbeef;
1901 dwLen = sizeof(DWORD);
1902 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1903 ok(result, "%08x\n", GetLastError());
1904 ok(dwVal ==
1905 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1906 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1907 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1908 " got %08x\n", dwVal);
1909
1910 /* The signature key's public key may also be exported.. */
1911 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1912 ok(result, "%08x\n", GetLastError());
1913 /* but its private key may not be. */
1914 SetLastError(0xdeadbeef);
1915 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1916 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1917 broken(result), /* Win9x/NT4 */
1918 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1919 /* Setting the permissions of the signature key isn't allowed, either. */
1920 dwVal |= CRYPT_EXPORT;
1921 SetLastError(0xdeadbeef);
1922 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1923 ok(!result &&
1924 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1925 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1926
1927 dwLen = 12;
1928 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1929 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1930
1931 CryptDestroyKey(hRSAKey);
1932 }
1933
1934 static void test_import_export(void)
1935 {
1936 DWORD dwLen, dwDataLen, dwVal;
1937 HCRYPTKEY hPublicKey, hPrivKey;
1938 BOOL result;
1939 ALG_ID algID;
1940 BYTE emptyKey[2048], *exported_key;
1941 static BYTE abPlainPublicKey[84] = {
1942 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1943 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1944 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1945 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1946 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1947 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1948 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1949 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1950 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1951 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1952 0x11, 0x11, 0x11, 0x11
1953 };
1954 static BYTE priv_key_with_high_bit[] = {
1955 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1956 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1957 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1958 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1959 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1960 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1961 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1962 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1963 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1964 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1965 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1966 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1967 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1968 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1969 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1970 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1971 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1972 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1973 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1974 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1975 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1976 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1977 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1978 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1979 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1980 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1981 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1982 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1983 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1984 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1985 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1986 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1987 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1988 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1989 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1990 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1991 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1992 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1993 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1994 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1995 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1996 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1997 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1998 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1999 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2000 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2001 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2002 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2003 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2004 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2005 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2006 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2007 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2008 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2009 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2010 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2011 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2012 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2013 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2014 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2015 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2016 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2017 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2018 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2019 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2020 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2021 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2022 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2023 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2024 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2025 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2026 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2027 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2028 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2029 0xb6, 0x5f, 0x01, 0x5e
2030 };
2031 static const BYTE expected_exported_priv_key[] = {
2032 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2033 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2034 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2035 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2036 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2037 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2038 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2039 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2040 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2041 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2042 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2043 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2044 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2045 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2046 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2047 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2048 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2049 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2050 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2051 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2052 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2053 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2054 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2055 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2056 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2057 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2058 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2059 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2060 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2061 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2062 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2063 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2064 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2065 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2066 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2067 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2068 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2069 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2070 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2071 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2072 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2073 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2074 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2075 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2076 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2077 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2078 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2079 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2080 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2081 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2082 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2083 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2084 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2085 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2086 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2087 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2088 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2089 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2090 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2091 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2092 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2093 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2094 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2095 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2096 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2097 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2098 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2099 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2100 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2101 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2102 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2103 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2104 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2105 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2106 0xb6, 0x5f, 0x01, 0x5e
2107 };
2108
2109 dwLen=84;
2110 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2111 ok(result, "failed to import the public key\n");
2112
2113 dwDataLen=sizeof(algID);
2114 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2115 ok(result, "failed to get the KP_ALGID from the imported public key\n");
2116 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2117
2118 dwVal = 0xdeadbeef;
2119 dwDataLen = sizeof(DWORD);
2120 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2121 ok(result, "%08x\n", GetLastError());
2122 ok(dwVal ==
2123 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2124 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2125 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2126 " got %08x\n", dwVal);
2127 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2128 ok(result, "failed to export the fresh imported public key\n");
2129 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2130 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2131
2132 CryptDestroyKey(hPublicKey);
2133
2134 result = CryptImportKey(hProv, priv_key_with_high_bit,
2135 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2136 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2137
2138 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2139 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2140 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2141 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2142 &dwDataLen);
2143 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2144
2145 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2146 dwDataLen);
2147 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2148 "unexpected value\n");
2149
2150 HeapFree(GetProcessHeap(), 0, exported_key);
2151
2152 CryptDestroyKey(hPrivKey);
2153 }
2154
2155 static void test_schannel_provider(void)
2156 {
2157 HCRYPTPROV hProv;
2158 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2159 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2160 BOOL result;
2161 DWORD dwLen;
2162 SCHANNEL_ALG saSChannelAlg;
2163 CRYPT_DATA_BLOB data_blob;
2164 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2165 BYTE abTLS1Master[140] = {
2166 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2167 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2168 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2169 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2170 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2171 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2172 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2173 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2174 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2175 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2176 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2177 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2178 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2179 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2180 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2181 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2182 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2183 0xd3, 0x1e, 0x82, 0xb3
2184 };
2185 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2186 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2187 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2188 BYTE abClientFinished[16] = "client finished";
2189 BYTE abData[16] = "Wine rocks!";
2190 BYTE abMD5Hash[16];
2191 static const BYTE abEncryptedData[16] = {
2192 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2193 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2194 };
2195 static const BYTE abPRF[16] = {
2196 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2197 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2198 };
2199 static const BYTE abMD5[16] = {
2200 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2201 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2202 };
2203
2204 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2205 if (!result)
2206 {
2207 win_skip("no PROV_RSA_SCHANNEL support\n");
2208 return;
2209 }
2210 ok (result, "%08x\n", GetLastError());
2211 if (result)
2212 CryptReleaseContext(hProv, 0);
2213
2214 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2215 ok (result, "%08x\n", GetLastError());
2216 if (!result) return;
2217
2218 /* To get deterministic results, we import the TLS1 master secret (which
2219 * is typically generated from a random generator). Therefore, we need
2220 * an RSA key. */
2221 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2222 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2223 ok (result, "%08x\n", GetLastError());
2224 if (!result) return;
2225
2226 dwLen = (DWORD)sizeof(abTLS1Master);
2227 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2228 ok (result, "%08x\n", GetLastError());
2229 if (!result) return;
2230
2231 /* Setting the TLS1 client and server random parameters, as well as the
2232 * MAC and encryption algorithm parameters. */
2233 data_blob.cbData = 33;
2234 data_blob.pbData = abClientSecret;
2235 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2236 ok (result, "%08x\n", GetLastError());
2237 if (!result) return;
2238
2239 data_blob.cbData = 33;
2240 data_blob.pbData = abServerSecret;
2241 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2242 ok (result, "%08x\n", GetLastError());
2243 if (!result) return;
2244
2245 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2246 saSChannelAlg.Algid = CALG_DES;
2247 saSChannelAlg.cBits = 64;
2248 saSChannelAlg.dwFlags = 0;
2249 saSChannelAlg.dwReserved = 0;
2250 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2251 ok (result, "%08x\n", GetLastError());
2252 if (!result) return;
2253
2254 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2255 saSChannelAlg.Algid = CALG_MD5;
2256 saSChannelAlg.cBits = 128;
2257 saSChannelAlg.dwFlags = 0;
2258 saSChannelAlg.dwReserved = 0;
2259 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2260 ok (result, "%08x\n", GetLastError());
2261 if (!result) return;
2262
2263 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2264 * (Keys can only be derived from hashes, not from other keys.) */
2265 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2266 ok (result, "%08x\n", GetLastError());
2267 if (!result) return;
2268
2269 /* Deriving the server write encryption key from the master hash */
2270 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2271 ok (result, "%08x\n", GetLastError());
2272 if (!result) return;
2273
2274 /* Encrypting some data with the server write encryption key and checking the result. */
2275 dwLen = 12;
2276 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2277 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2278
2279 /* Second test case: Test the TLS1 pseudo random number function. */
2280 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2281 ok (result, "%08x\n", GetLastError());
2282 if (!result) return;
2283
2284 /* Set the label and seed parameters for the random number function */
2285 data_blob.cbData = 36;
2286 data_blob.pbData = abHashedHandshakes;
2287 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2288 ok (result, "%08x\n", GetLastError());
2289 if (!result) return;
2290
2291 data_blob.cbData = 15;
2292 data_blob.pbData = abClientFinished;
2293 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2294 ok (result, "%08x\n", GetLastError());
2295 if (!result) return;
2296
2297 /* Generate some pseudo random bytes and check if they are correct. */
2298 dwLen = (DWORD)sizeof(abData);
2299 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2300 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2301 "%08x\n", GetLastError());
2302
2303 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2304 * Hash some data with the HMAC. Compare results. */
2305 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2306 ok (result, "%08x\n", GetLastError());
2307 if (!result) return;
2308
2309 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2310 ok (result, "%08x\n", GetLastError());
2311 if (!result) return;
2312
2313 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2314 ok (result, "%08x\n", GetLastError());
2315 if (!result) return;
2316
2317 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2318 ok (result, "%08x\n", GetLastError());
2319 if (!result) return;
2320
2321 dwLen = (DWORD)sizeof(abMD5Hash);
2322 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2323 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2324
2325 CryptDestroyHash(hHMAC);
2326 CryptDestroyHash(hTLS1PRF);
2327 CryptDestroyHash(hMasterHash);
2328 CryptDestroyKey(hServerWriteMACKey);
2329 CryptDestroyKey(hServerWriteKey);
2330 CryptDestroyKey(hRSAKey);
2331 CryptDestroyKey(hMasterSecret);
2332 CryptReleaseContext(hProv, 0);
2333 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2334 }
2335
2336 /* Test that a key can be used to encrypt data and exported, and that, when
2337 * the exported key is imported again, can be used to decrypt the original
2338 * data again.
2339 */
2340 static void test_rsa_round_trip(void)
2341 {
2342 static const char test_string[] = "Well this is a fine how-do-you-do.";
2343 HCRYPTPROV prov;
2344 HCRYPTKEY signKey, keyExchangeKey;
2345 BOOL result;
2346 BYTE data[256], *exportedKey;
2347 DWORD dataLen, keyLen;
2348
2349 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2350 CRYPT_DELETEKEYSET);
2351
2352 /* Generate a new key... */
2353 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2354 CRYPT_NEWKEYSET);
2355 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2356 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2357 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2358 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2359 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2360 /* encrypt some data with it... */
2361 memcpy(data, test_string, strlen(test_string) + 1);
2362 dataLen = strlen(test_string) + 1;
2363 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2364 sizeof(data));
2365 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2366 "CryptEncrypt failed: %08x\n", GetLastError());
2367 /* export the key... */
2368 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2369 &keyLen);
2370 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2371 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2372 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2373 &keyLen);
2374 /* destroy the key... */
2375 CryptDestroyKey(keyExchangeKey);
2376 CryptDestroyKey(signKey);
2377 /* import the key again... */
2378 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2379 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2380 HeapFree(GetProcessHeap(), 0, exportedKey);
2381 /* and decrypt the data encrypted with the original key with the imported
2382 * key.
2383 */
2384 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2385 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2386 "CryptDecrypt failed: %08x\n", GetLastError());
2387 if (result)
2388 {
2389 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2390 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2391 }
2392 CryptDestroyKey(keyExchangeKey);
2393 CryptReleaseContext(prov, 0);
2394
2395 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2396 CRYPT_DELETEKEYSET);
2397 }
2398
2399 static void test_enum_container(void)
2400 {
2401 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2402 DWORD dwBufferLen;
2403 BOOL result, fFound = FALSE;
2404
2405 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2406 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2407 SetLastError(0xdeadbeef);
2408 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2409 ok (result, "%08x\n", GetLastError());
2410 ok (dwBufferLen == MAX_PATH + 1 ||
2411 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2412 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2413
2414 /* If the result fits into abContainerName dwBufferLen is left untouched */
2415 dwBufferLen = (DWORD)sizeof(abContainerName);
2416 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2417 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2418
2419 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2420 do {
2421 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2422 dwBufferLen = (DWORD)sizeof(abContainerName);
2423 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2424
2425 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2426 }
2427
2428 static BYTE signBlob[] = {
2429 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2430 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2431 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2432 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2433 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2434 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2435 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2436 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2437 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2438 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2439 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2440 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2441 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2442 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2443 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2444 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2445 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2446 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2447 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2448 0xb6,0x85,0x86,0x07 };
2449
2450 static void test_null_provider(void)
2451 {
2452 HCRYPTPROV prov;
2453 HCRYPTKEY key;
2454 BOOL result;
2455 DWORD keySpec, dataLen,dwParam;
2456 char szName[MAX_PATH];
2457
2458 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2459 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2460 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2461 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2462 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2463 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2464 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2465 CRYPT_DELETEKEYSET);
2466 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2467 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2468 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2469 CRYPT_DELETEKEYSET);
2470 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2471 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2472 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2473 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2474 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2475
2476 /* Delete the default container. */
2477 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2478 /* Once you've deleted the default container you can't open it as if it
2479 * already exists.
2480 */
2481 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2482 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2483 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2484 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2485 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2486 CRYPT_VERIFYCONTEXT);
2487 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2488 if (!result) return;
2489 dataLen = sizeof(keySpec);
2490 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2491 if (result)
2492 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2493 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2494 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2495 * supported, you can't get the keys from this container.
2496 */
2497 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2498 ok(!result && GetLastError() == NTE_NO_KEY,
2499 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2500 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2501 ok(!result && GetLastError() == NTE_NO_KEY,
2502 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2503 result = CryptReleaseContext(prov, 0);
2504 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2505 /* You can create a new default container. */
2506 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2507 CRYPT_NEWKEYSET);
2508 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2509 /* But you still can't get the keys (until one's been generated.) */
2510 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2511 ok(!result && GetLastError() == NTE_NO_KEY,
2512 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2513 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2514 ok(!result && GetLastError() == NTE_NO_KEY,
2515 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2516 CryptReleaseContext(prov, 0);
2517 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2518
2519 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2520 CRYPT_DELETEKEYSET);
2521 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2522 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2523 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2524 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2525 CRYPT_VERIFYCONTEXT);
2526 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2527 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2528 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2529 CRYPT_NEWKEYSET);
2530 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2531 if (!result) return;
2532 /* Test provider parameters getter */
2533 dataLen = sizeof(dwParam);
2534 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2535 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2536 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2537 dataLen = sizeof(dwParam);
2538 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2539 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2540 "Expected 0, got 0x%08X\n",dwParam);
2541 dataLen = sizeof(dwParam);
2542 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2543 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2544 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2545 dataLen = sizeof(keySpec);
2546 SetLastError(0xdeadbeef);
2547 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2548 if (!result && GetLastError() == NTE_BAD_TYPE)
2549 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2550 else
2551 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2552 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2553 /* PP_CONTAINER parameter */
2554 dataLen = sizeof(szName);
2555 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2556 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2557 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2558 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2559 /* PP_UNIQUE_CONTAINER parameter */
2560 dataLen = sizeof(szName);
2561 SetLastError(0xdeadbeef);
2562 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2563 if (!result && GetLastError() == NTE_BAD_TYPE)
2564 {
2565 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2566 }
2567 else
2568 {
2569 char container[MAX_PATH];
2570
2571 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2572 uniquecontainer(container);
2573 todo_wine
2574 {
2575 ok(dataLen == strlen(container)+1 ||
2576 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2577 "Expected a param length of 70, got %d\n", dataLen);
2578 ok(!strcmp(container, szName) ||
2579 broken(!strcmp(szName, szContainer)) /* WinME */,
2580 "Wrong container name : %s\n", szName);
2581 }
2582 }
2583 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2584 ok(!result && GetLastError() == NTE_NO_KEY,
2585 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2586 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2587 ok(!result && GetLastError() == NTE_NO_KEY,
2588 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2589
2590 /* Importing a key exchange blob.. */
2591 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2592 0, 0, &key);
2593 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2594 CryptDestroyKey(key);
2595 /* allows access to the key exchange key.. */
2596 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2597 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2598 CryptDestroyKey(key);
2599 /* but not to the private key. */
2600 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2601 ok(!result && GetLastError() == NTE_NO_KEY,
2602 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2603 CryptReleaseContext(prov, 0);
2604 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2605 CRYPT_DELETEKEYSET);
2606
2607 /* Whereas importing a sign blob.. */
2608 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2609 CRYPT_NEWKEYSET);
2610 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2611 if (!result) return;
2612 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2613 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2614 CryptDestroyKey(key);
2615 /* doesn't allow access to the key exchange key.. */
2616 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2617 ok(!result && GetLastError() == NTE_NO_KEY,
2618 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2619 /* but does to the private key. */
2620 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2621 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2622 CryptDestroyKey(key);
2623 CryptReleaseContext(prov, 0);
2624
2625 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2626 CRYPT_DELETEKEYSET);
2627
2628 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2629 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2630 CRYPT_NEWKEYSET);
2631 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2632 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2633 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2634 CryptDestroyKey(key);
2635 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2636 ok(!result, "expected CryptGetUserKey to fail\n");
2637 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2638 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2639 CryptDestroyKey(key);
2640 CryptReleaseContext(prov, 0);
2641
2642 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2643 CRYPT_DELETEKEYSET);
2644
2645 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2646 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2647 CRYPT_NEWKEYSET);
2648 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2649 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2650 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2651 CryptDestroyKey(key);
2652 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2653 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2654 CryptDestroyKey(key);
2655 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2656 ok(!result, "expected CryptGetUserKey to fail\n");
2657 CryptReleaseContext(prov, 0);
2658
2659 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2660 CRYPT_DELETEKEYSET);
2661
2662 /* test for the bug in accessing the user key in a container
2663 */
2664 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2665 CRYPT_NEWKEYSET);
2666 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2667 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2668 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2669 CryptDestroyKey(key);
2670 CryptReleaseContext(prov,0);
2671 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2672 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2673 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2674 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2675 CryptDestroyKey(key);
2676 CryptReleaseContext(prov, 0);
2677
2678 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2679 CRYPT_DELETEKEYSET);
2680
2681 /* test the machine key set */
2682 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2683 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2684 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2685 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2686 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2687 CryptReleaseContext(prov, 0);
2688 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2689 CRYPT_MACHINE_KEYSET);
2690 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2691 CryptReleaseContext(prov,0);
2692 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2693 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2694 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2695 GetLastError());
2696 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2697 CRYPT_MACHINE_KEYSET);
2698 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2699 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2700
2701 }
2702
2703 static void test_key_permissions(void)
2704 {
2705 HCRYPTKEY hKey1, hKey2;
2706 DWORD dwVal, dwLen;
2707 BOOL result;
2708
2709 /* Create keys that are exportable */
2710 if (!init_base_environment(CRYPT_EXPORTABLE))
2711 return;
2712
2713 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2714 ok (result, "%08x\n", GetLastError());
2715 if (!result) return;
2716
2717 dwVal = 0xdeadbeef;
2718 dwLen = sizeof(DWORD);
2719 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2720 ok(result, "%08x\n", GetLastError());
2721 ok(dwVal ==
2722 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2723 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2724 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2725 " got %08x\n", dwVal);
2726
2727 /* The key exchange key's public key may be exported.. */
2728 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2729 ok(result, "%08x\n", GetLastError());
2730 /* and its private key may be too. */
2731 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2732 ok(result, "%08x\n", GetLastError());
2733 /* Turning off the key's export permissions is "allowed".. */
2734 dwVal &= ~CRYPT_EXPORT;
2735 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2736 ok(result ||
2737 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2738 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2739 "%08x\n", GetLastError());
2740 /* but it has no effect. */
2741 dwVal = 0xdeadbeef;
2742 dwLen = sizeof(DWORD);
2743 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2744 ok(result, "%08x\n", GetLastError());
2745 ok(dwVal ==
2746 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2747 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2748 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2749 " got %08x\n", dwVal);
2750 /* Thus, changing the export flag of the key doesn't affect whether the key
2751 * may be exported.
2752 */
2753 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2754 ok(result, "%08x\n", GetLastError());
2755
2756 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2757 ok (result, "%08x\n", GetLastError());
2758
2759 /* A subsequent get of the same key, into a different handle, also doesn't
2760 * show that the permissions have been changed.
2761 */
2762 dwVal = 0xdeadbeef;
2763 dwLen = sizeof(DWORD);
2764 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2765 ok(result, "%08x\n", GetLastError());
2766 ok(dwVal ==
2767 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2768 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2769 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2770 " got %08x\n", dwVal);
2771
2772 CryptDestroyKey(hKey2);
2773 CryptDestroyKey(hKey1);
2774
2775 clean_up_base_environment();
2776 }
2777
2778 static void test_key_initialization(void)
2779 {
2780 DWORD dwLen;
2781 HCRYPTPROV prov1, prov2;
2782 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2783 BOOL result;
2784 static BYTE abSessionKey[148] = {
2785 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2786 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2787 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2788 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2789 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2790 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2791 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2792 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2793 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2794 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2795 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2796 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2797 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2798 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2799 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2800 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2801 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2802 0x04, 0x8c, 0x49, 0x92
2803 };
2804
2805 /* Like init_base_environment, but doesn't generate new keys, as they'll
2806 * be imported instead.
2807 */
2808 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2809 {
2810 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2811 CRYPT_NEWKEYSET);
2812 ok(result, "%08x\n", GetLastError());
2813 }
2814 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2815 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2816
2817 dwLen = (DWORD)sizeof(abSessionKey);
2818 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2819 ok(result, "%08x\n", GetLastError());
2820
2821 /* Once the key has been imported, subsequently acquiring a context with
2822 * the same name will allow retrieving the key.
2823 */
2824 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2825 ok(result, "%08x\n", GetLastError());
2826 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2827 ok(result, "%08x\n", GetLastError());
2828 if (result) CryptDestroyKey(hKey);
2829 CryptReleaseContext(prov2, 0);
2830
2831 CryptDestroyKey(hSessionKey);
2832 CryptDestroyKey(hKeyExchangeKey);
2833 CryptReleaseContext(prov1, 0);
2834 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2835 CRYPT_DELETEKEYSET);
2836 }
2837
2838 START_TEST(rsaenh)
2839 {
2840 if (!init_base_environment(0))
2841 return;
2842 test_prov();
2843 test_gen_random();
2844 test_hashes();
2845 test_rc4();
2846 test_rc2();
2847 test_des();
2848 test_3des112();
2849 test_3des();
2850 test_hmac();
2851 test_mac();
2852 test_block_cipher_modes();
2853 test_import_private();
2854 test_verify_signature();
2855 test_rsa_encrypt();
2856 test_import_export();
2857 test_enum_container();
2858 clean_up_base_environment();
2859 test_key_permissions();
2860 test_key_initialization();
2861 test_schannel_provider();
2862 test_null_provider();
2863 test_rsa_round_trip();
2864 if (!init_aes_environment())
2865 return;
2866 test_aes(128);
2867 test_aes(192);
2868 test_aes(256);
2869 test_sha2();
2870 clean_up_aes_environment();
2871 }