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