rsaenh: Fail on unsupported flag values only in CryptHashData().
[wine/multimedia.git] / dlls / rsaenh / tests / rsaenh.c
blob84505f8d96e710c31d6497d8817c4f151cbf0b9c
1 /*
2 * Unit tests for rsaenh functions
4 * Copyright (c) 2004 Michael Jung
5 * Copyright (c) 2006 Juan Lang
6 * Copyright (c) 2007 Vijay Kiran Kamuju
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <string.h>
24 #include <stdio.h>
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wincrypt.h"
30 #include "winreg.h"
32 static HCRYPTPROV hProv;
33 static const char szContainer[] = "winetest";
34 static const char szProvider[] = MS_ENHANCED_PROV_A;
36 typedef struct _ctdatatype {
37 unsigned char origstr[32];
38 unsigned char decstr[32];
39 int strlen;
40 int enclen;
41 int buflen;
42 } cryptdata;
44 static const cryptdata cTestData[4] = {
45 {"abcdefghijkl",
46 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
47 12,8,16},
48 {"abcdefghij",
49 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
50 10,8,16},
51 {"abcdefgh",
52 {'a','b','c','d','e','f','g','h',0},
53 8,8,16},
54 {"abcdefghijkl",
55 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
56 12,12,16}
60 * 1. Take the MD5 Hash of the container name (with an extra null byte)
61 * 2. Turn the hash into a 4 DWORD hex value
62 * 3. Append a '_'
63 * 4. Add the MachineGuid
66 static void uniquecontainer(char *unique)
68 /* MD5 hash of "winetest\0" in 4 DWORD hex */
69 static const char szContainer_md5[] = "9d20fd8d05ed2b8455d125d0bf6d6a70";
70 static const char szCryptography[] = "Software\\Microsoft\\Cryptography";
71 static const char szMachineGuid[] = "MachineGuid";
72 HKEY hkey;
73 char guid[MAX_PATH];
74 DWORD size = MAX_PATH;
75 HRESULT ret;
77 /* Get the MachineGUID */
78 ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szCryptography, 0, KEY_READ | KEY_WOW64_64KEY, &hkey);
79 if (ret == ERROR_ACCESS_DENIED)
81 /* Windows 2000 can't handle KEY_WOW64_64KEY */
82 RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
84 RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
85 RegCloseKey(hkey);
87 lstrcpy(unique, szContainer_md5);
88 lstrcat(unique, "_");
89 lstrcat(unique, guid);
92 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
94 size_t i;
95 printf("%s: ",heading);
96 for(i=0;i<cb;i++)
97 printf("0x%02x,",pb[i]);
98 putchar('\n');
101 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
104 static void trace_hex(BYTE *pbData, DWORD dwLen) {
105 char szTemp[256];
106 DWORD i, j;
108 for (i = 0; i < dwLen-7; i+=8) {
109 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
110 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
111 pbData[i+6], pbData[i+7]);
112 trace(szTemp);
114 for (j=0; i<dwLen; j++,i++) {
115 sprintf(szTemp+6*j, "0x%02x,\n", pbData[i]);
117 trace(szTemp);
121 static int init_base_environment(DWORD dwKeyFlags)
123 HCRYPTKEY hKey;
124 BOOL result;
126 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
128 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
130 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
131 ok(!result && (GetLastError()==NTE_BAD_FLAGS ||
132 broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */)),
133 "%d, %08x\n", result, GetLastError());
135 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
137 ok(GetLastError()==NTE_BAD_KEYSET ||
138 broken(GetLastError() == NTE_TEMPORARY_PROFILE /* some Win7 setups */) ||
139 broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */),
140 "%08x\n", GetLastError());
141 if (GetLastError()!=NTE_BAD_KEYSET)
143 win_skip("RSA full provider not available\n");
144 return 0;
146 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
147 CRYPT_NEWKEYSET);
148 ok(result, "%08x\n", GetLastError());
149 if (!result)
151 win_skip("Couldn't create crypto provider\n");
152 return 0;
154 result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey);
155 ok(result, "%08x\n", GetLastError());
156 if (result) CryptDestroyKey(hKey);
157 result = CryptGenKey(hProv, AT_SIGNATURE, dwKeyFlags, &hKey);
158 ok(result, "%08x\n", GetLastError());
159 if (result) CryptDestroyKey(hKey);
161 return 1;
164 static void clean_up_base_environment(void)
166 BOOL result;
168 SetLastError(0xdeadbeef);
169 result = CryptReleaseContext(hProv, 1);
170 ok(!result || broken(result) /* Win98 */, "Expected failure\n");
171 ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
173 /* Just to prove that Win98 also released the CSP */
174 SetLastError(0xdeadbeef);
175 result = CryptReleaseContext(hProv, 0);
176 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
178 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
181 static int init_aes_environment(void)
183 HCRYPTKEY hKey;
184 BOOL result;
186 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
188 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
190 /* we are using NULL as provider name for RSA_AES provider as the provider
191 * names are different in Windows XP and Vista. Its different as to what
192 * its defined in the SDK on Windows XP.
193 * This provider is available on Windows XP, Windows 2003 and Vista. */
195 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
196 if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
198 win_skip("RSA_AES provider not supported\n");
199 return 0;
201 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
203 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
205 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
206 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
207 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
208 CRYPT_NEWKEYSET);
209 ok(result, "%08x\n", GetLastError());
210 if (!result) return 0;
211 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
212 ok(result, "%08x\n", GetLastError());
213 if (result) CryptDestroyKey(hKey);
214 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
215 ok(result, "%08x\n", GetLastError());
216 if (result) CryptDestroyKey(hKey);
218 return 1;
221 static void clean_up_aes_environment(void)
223 BOOL result;
225 result = CryptReleaseContext(hProv, 1);
226 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
228 CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
231 static void test_prov(void)
233 BOOL result;
234 DWORD dwLen, dwInc;
236 dwLen = (DWORD)sizeof(DWORD);
237 SetLastError(0xdeadbeef);
238 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
239 if (!result && GetLastError() == NTE_BAD_TYPE)
240 skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
241 else
242 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
244 dwLen = (DWORD)sizeof(DWORD);
245 SetLastError(0xdeadbeef);
246 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
247 if (!result && GetLastError() == NTE_BAD_TYPE)
248 skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
249 else
250 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
253 static void test_gen_random(void)
255 BOOL result;
256 BYTE rnd1[16], rnd2[16];
258 memset(rnd1, 0, sizeof(rnd1));
259 memset(rnd2, 0, sizeof(rnd2));
261 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
262 if (!result && GetLastError() == NTE_FAIL) {
263 /* rsaenh compiled without OpenSSL */
264 return;
267 ok(result, "%08x\n", GetLastError());
269 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
270 ok(result, "%08x\n", GetLastError());
272 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
275 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
277 HCRYPTHASH hHash;
278 BOOL result;
279 unsigned char pbData[2000];
280 int i;
282 *phKey = 0;
283 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
284 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
285 if (!result) {
286 /* rsaenh compiled without OpenSSL */
287 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
288 return FALSE;
290 ok(result, "%08x\n", GetLastError());
291 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
292 ok(result, "%08x\n", GetLastError());
293 if (!result) return FALSE;
294 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
295 ok(result, "%08x\n", GetLastError());
296 if (!result) return FALSE;
297 len = 2000;
298 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
299 ok(result, "%08x\n", GetLastError());
300 CryptDestroyHash(hHash);
301 return TRUE;
304 static BYTE abPlainPrivateKey[596] = {
305 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
306 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
307 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
308 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
309 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
310 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
311 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
312 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
313 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
314 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
315 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
316 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
317 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
318 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
319 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
320 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
321 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
322 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
323 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
324 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
325 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
326 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
327 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
328 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
329 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
330 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
331 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
332 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
333 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
334 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
335 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
336 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
337 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
338 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
339 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
340 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
341 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
342 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
343 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
344 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
345 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
346 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
347 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
348 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
349 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
350 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
351 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
352 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
353 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
354 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
355 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
356 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
357 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
358 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
359 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
360 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
361 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
362 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
363 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
364 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
365 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
366 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
367 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
368 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
369 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
370 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
371 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
372 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
373 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
374 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
375 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
376 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
377 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
378 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
379 0xf2, 0x5d, 0x58, 0x07
382 static void test_hashes(void)
384 static const unsigned char md2hash[16] = {
385 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
386 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
387 static const unsigned char md4hash[16] = {
388 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
389 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
390 static const unsigned char empty_md5hash[16] = {
391 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
392 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
393 static const unsigned char md5hash[16] = {
394 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
395 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
396 static const unsigned char sha1hash[20] = {
397 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
398 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
399 static const unsigned char signed_ssl3_shamd5_hash[] = {
400 0x4f,0xcc,0x2f,0x33,0x44,0x60,0x76,0x16,0x13,0xc8,0xff,0xd4,0x59,0x19,
401 0xde,0x85,0x44,0x72,0x47,0x98,0x01,0xfb,0x67,0x5c,0x5b,0x35,0x15,0x0f,
402 0x91,0xda,0xc7,0x7c,0xfb,0xe2,0x18,0xef,0xac,0x31,0x40,0x7b,0xa9,0x83,
403 0xdb,0x30,0xcd,0x94,0x4b,0x8e,0x3b,0x6c,0x7a,0x86,0x59,0xf0,0xd1,0xd2,
404 0x5e,0xce,0xd4,0x1b,0x7f,0xed,0x24,0xee,0x53,0x5c,0x15,0x97,0x21,0x7c,
405 0x5c,0xea,0xab,0xf5,0xd6,0x4b,0xb3,0xbb,0x14,0xf5,0x59,0x9e,0x21,0x90,
406 0x21,0x99,0x19,0xad,0xa2,0xa6,0xea,0x61,0xc1,0x41,0xe2,0x70,0x77,0xf7,
407 0x15,0x68,0x96,0x1e,0x5c,0x84,0x97,0xe3,0x5c,0xd2,0xd9,0xfb,0x87,0x6f,
408 0x11,0x21,0x82,0x43,0x76,0x32,0xa4,0x38,0x7b,0x85,0x22,0x30,0x1e,0x55,
409 0x79,0x93 };
410 unsigned char pbData[2048];
411 BOOL result;
412 HCRYPTHASH hHash, hHashClone;
413 HCRYPTPROV prov;
414 BYTE pbHashValue[36];
415 BYTE pbSigValue[128];
416 HCRYPTKEY hKeyExchangeKey;
417 DWORD hashlen, len, error;
418 int i;
420 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
422 /* MD2 Hashing */
423 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
424 if (!result) {
425 /* rsaenh compiled without OpenSSL */
426 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
427 } else {
428 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
429 ok(result, "%08x\n", GetLastError());
431 len = sizeof(DWORD);
432 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
433 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
435 len = 16;
436 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
437 ok(result, "%08x\n", GetLastError());
439 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
441 result = CryptDestroyHash(hHash);
442 ok(result, "%08x\n", GetLastError());
445 /* MD4 Hashing */
446 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
447 ok(result, "%08x\n", GetLastError());
449 result = CryptHashData(hHash, pbData, sizeof(pbData), ~0);
450 ok(!result && GetLastError() == NTE_BAD_FLAGS, "%08x\n", GetLastError());
452 result = CryptHashData(hHash, pbData, sizeof(pbData), CRYPT_USERDATA);
453 ok(result, "%08x\n", GetLastError());
455 len = sizeof(DWORD);
456 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
457 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
459 len = 16;
460 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
461 ok(result, "%08x\n", GetLastError());
463 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
465 result = CryptDestroyHash(hHash);
466 ok(result, "%08x\n", GetLastError());
468 /* MD5 Hashing */
469 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
470 ok(result, "%08x\n", GetLastError());
472 len = sizeof(DWORD);
473 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
474 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
476 result = CryptHashData(hHash, pbData, sizeof(pbData), ~0);
477 ok(!result && GetLastError() == NTE_BAD_FLAGS, "%08x\n", GetLastError());
479 result = CryptHashData(hHash, pbData, sizeof(pbData), CRYPT_USERDATA);
480 ok(result, "%08x\n", GetLastError());
482 len = 16;
483 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
484 ok(result, "%08x\n", GetLastError());
486 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
488 result = CryptDestroyHash(hHash);
489 ok(result, "%08x\n", GetLastError());
491 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
492 ok(result, "%08x\n", GetLastError());
494 /* The hash is available even if CryptHashData hasn't been called */
495 len = 16;
496 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
497 ok(result, "%08x\n", GetLastError());
499 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
501 /* It's also stable: getting it twice results in the same value */
502 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
503 ok(result, "%08x\n", GetLastError());
505 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
507 /* Can't add data after the hash been retrieved */
508 SetLastError(0xdeadbeef);
509 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
510 ok(!result, "Expected failure\n");
511 ok(GetLastError() == NTE_BAD_HASH_STATE ||
512 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
513 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
515 /* You can still retrieve the hash, its value just hasn't changed */
516 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
517 ok(result, "%08x\n", GetLastError());
519 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
521 result = CryptDestroyHash(hHash);
522 ok(result, "%08x\n", GetLastError());
524 /* SHA1 Hashing */
525 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
526 ok(result, "%08x\n", GetLastError());
528 result = CryptHashData(hHash, pbData, 5, CRYPT_USERDATA);
529 ok(result, "%08x\n", GetLastError());
531 if(pCryptDuplicateHash) {
532 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
533 ok(result, "%08x\n", GetLastError());
535 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
536 ok(result, "%08x\n", GetLastError());
538 len = sizeof(DWORD);
539 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
540 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
542 len = 20;
543 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
544 ok(result, "%08x\n", GetLastError());
546 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
548 result = CryptDestroyHash(hHashClone);
549 ok(result, "%08x\n", GetLastError());
552 result = CryptDestroyHash(hHash);
553 ok(result, "%08x\n", GetLastError());
555 /* The SHA-2 variants aren't supported in the RSA full provider */
556 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
557 ok(!result && GetLastError() == NTE_BAD_ALGID,
558 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
559 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
560 ok(!result && GetLastError() == NTE_BAD_ALGID,
561 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
562 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
563 ok(!result && GetLastError() == NTE_BAD_ALGID,
564 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
566 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
567 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
569 result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash);
570 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
572 /* release provider before using the hash */
573 result = CryptReleaseContext(prov, 0);
574 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
576 SetLastError(0xdeadbeef);
577 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
578 error = GetLastError();
579 ok(!result, "CryptHashData succeeded\n");
580 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
582 SetLastError(0xdeadbeef);
583 result = CryptDestroyHash(hHash);
584 error = GetLastError();
585 ok(!result, "CryptDestroyHash succeeded\n");
586 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
588 if (!pCryptDuplicateHash)
590 win_skip("CryptDuplicateHash is not available\n");
591 return;
594 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
595 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
597 result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
598 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
600 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
601 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
603 result = pCryptDuplicateHash(hHash, NULL, 0, &hHashClone);
604 ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
606 len = 20;
607 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
608 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
610 /* add data after duplicating the hash */
611 result = CryptHashData(hHash, (const BYTE *)"more data", sizeof("more data"), 0);
612 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
614 result = CryptDestroyHash(hHash);
615 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
617 result = CryptDestroyHash(hHashClone);
618 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
620 result = CryptReleaseContext(prov, 0);
621 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
623 /* Test CALG_SSL3_SHAMD5 */
624 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
625 ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
627 /* Step 1: create an MD5 hash of the data */
628 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
629 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
630 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
631 ok(result, "%08x\n", GetLastError());
632 len = 16;
633 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
634 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
635 result = CryptDestroyHash(hHash);
636 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
637 /* Step 2: create a SHA1 hash of the data */
638 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
639 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
640 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
641 ok(result, "%08x\n", GetLastError());
642 len = 20;
643 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue + 16, &len, 0);
644 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
645 result = CryptDestroyHash(hHash);
646 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
647 /* Step 3: create a CALG_SSL3_SHAMD5 hash handle */
648 result = CryptCreateHash(hProv, CALG_SSL3_SHAMD5, 0, 0, &hHash);
649 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
650 /* Test that CryptHashData fails on this hash */
651 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
652 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
653 result = CryptSetHashParam(hHash, HP_HASHVAL, pbHashValue, 0);
654 ok(result, "%08x\n", GetLastError());
655 len = (DWORD)sizeof(abPlainPrivateKey);
656 result = CryptImportKey(hProv, abPlainPrivateKey, len, 0, 0, &hKeyExchangeKey);
657 ok(result, "%08x\n", GetLastError());
658 len = 0;
659 result = CryptSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &len);
660 ok(result, "%08x\n", GetLastError());
661 ok(len == 128, "expected len 128, got %d\n", len);
662 result = CryptSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, pbSigValue, &len);
663 ok(result, "%08x\n", GetLastError());
664 ok(!memcmp(pbSigValue, signed_ssl3_shamd5_hash, len), "unexpected value\n");
665 if (len != 128 || memcmp(pbSigValue, signed_ssl3_shamd5_hash, len))
667 printBytes("expected", signed_ssl3_shamd5_hash,
668 sizeof(signed_ssl3_shamd5_hash));
669 printBytes("got", pbSigValue, len);
671 result = CryptDestroyKey(hKeyExchangeKey);
672 ok(result, "CryptDestroyKey failed 0x%08x\n", GetLastError());
673 result = CryptDestroyHash(hHash);
674 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
675 result = CryptReleaseContext(prov, 0);
676 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
679 static void test_block_cipher_modes(void)
681 static const BYTE plain[23] = {
682 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
683 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
684 static const BYTE ecb[24] = {
685 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
686 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
687 static const BYTE cbc[24] = {
688 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
689 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
690 static const BYTE cfb[24] = {
691 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
692 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
693 HCRYPTKEY hKey;
694 BOOL result;
695 BYTE abData[24];
696 DWORD dwMode, dwLen;
698 result = derive_key(CALG_RC2, &hKey, 40);
699 if (!result) return;
701 memcpy(abData, plain, sizeof(plain));
703 dwMode = CRYPT_MODE_ECB;
704 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
705 ok(result, "%08x\n", GetLastError());
707 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
708 ok(result, "%08x\n", GetLastError());
709 ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
711 dwLen = 23;
712 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
713 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
714 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
716 SetLastError(ERROR_SUCCESS);
717 dwLen = 23;
718 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
719 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
720 "%08x, dwLen: %d\n", GetLastError(), dwLen);
722 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
723 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
724 "%08x, dwLen: %d\n", GetLastError(), dwLen);
726 dwMode = CRYPT_MODE_CBC;
727 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
728 ok(result, "%08x\n", GetLastError());
730 dwLen = 23;
731 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
732 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
733 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
735 dwLen = 23;
736 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
737 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
738 "%08x, dwLen: %d\n", GetLastError(), dwLen);
740 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
741 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
742 "%08x, dwLen: %d\n", GetLastError(), dwLen);
744 dwMode = CRYPT_MODE_CFB;
745 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
746 ok(result, "%08x\n", GetLastError());
748 dwLen = 16;
749 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
750 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
752 dwLen = 7;
753 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
754 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
755 "%08x, dwLen: %d\n", GetLastError(), dwLen);
757 dwLen = 8;
758 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
759 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
761 dwLen = 16;
762 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
763 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
764 "%08x, dwLen: %d\n", GetLastError(), dwLen);
766 dwMode = CRYPT_MODE_OFB;
767 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
768 ok(result, "%08x\n", GetLastError());
770 dwLen = 23;
771 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
772 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
774 CryptDestroyKey(hKey);
777 static void test_3des112(void)
779 HCRYPTKEY hKey;
780 BOOL result;
781 DWORD dwLen;
782 unsigned char pbData[16], enc_data[16], bad_data[16];
783 int i;
785 result = derive_key(CALG_3DES_112, &hKey, 0);
786 if (!result) {
787 /* rsaenh compiled without OpenSSL */
788 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
789 return;
792 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
794 dwLen = 13;
795 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
796 ok(result, "%08x\n", GetLastError());
798 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
799 ok(result, "%08x\n", GetLastError());
801 for (i=0; i<4; i++)
803 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
805 dwLen = cTestData[i].enclen;
806 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
807 ok(result, "%08x\n", GetLastError());
808 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
809 memcpy(enc_data, pbData, cTestData[i].buflen);
811 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
812 ok(result, "%08x\n", GetLastError());
813 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
814 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
815 if((dwLen != cTestData[i].enclen) ||
816 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
818 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
819 printBytes("got",pbData,dwLen);
822 /* Test bad data:
823 Decrypting a block of bad data with Final = TRUE should restore the
824 initial state of the key as well as decrypting a block of good data.
827 /* Changing key state by setting Final = FALSE */
828 dwLen = cTestData[i].buflen;
829 memcpy(pbData, enc_data, cTestData[i].buflen);
830 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
831 ok(result, "%08x\n", GetLastError());
833 /* Restoring key state by decrypting bad_data with Final = TRUE */
834 memcpy(bad_data, enc_data, cTestData[i].buflen);
835 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
836 SetLastError(0xdeadbeef);
837 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
838 ok(!result, "CryptDecrypt should failed!\n");
839 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
840 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
841 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
843 /* Checking key state */
844 dwLen = cTestData[i].buflen;
845 memcpy(pbData, enc_data, cTestData[i].buflen);
846 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
847 ok(result, "%08x\n", GetLastError());
848 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
849 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
850 if((dwLen != cTestData[i].enclen) ||
851 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
853 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
854 printBytes("got",pbData,dwLen);
857 result = CryptDestroyKey(hKey);
858 ok(result, "%08x\n", GetLastError());
861 static void test_des(void)
863 HCRYPTKEY hKey;
864 BOOL result;
865 DWORD dwLen, dwMode;
866 unsigned char pbData[16], enc_data[16], bad_data[16];
867 int i;
869 result = derive_key(CALG_DES, &hKey, 56);
870 if (!result) {
871 /* rsaenh compiled without OpenSSL */
872 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
873 return;
876 dwMode = CRYPT_MODE_ECB;
877 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
878 ok(result, "%08x\n", GetLastError());
880 dwLen = sizeof(DWORD);
881 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
882 ok(result, "%08x\n", GetLastError());
884 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
886 dwLen = 13;
887 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
888 ok(result, "%08x\n", GetLastError());
890 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
891 ok(result, "%08x\n", GetLastError());
893 for (i=0; i<4; i++)
895 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
897 dwLen = cTestData[i].enclen;
898 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
899 ok(result, "%08x\n", GetLastError());
900 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
901 memcpy(enc_data, pbData, cTestData[i].buflen);
903 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
904 ok(result, "%08x\n", GetLastError());
905 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
906 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
907 if((dwLen != cTestData[i].enclen) ||
908 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
910 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
911 printBytes("got",pbData,dwLen);
914 /* Test bad data:
915 Decrypting a block of bad data with Final = TRUE should restore the
916 initial state of the key as well as decrypting a block of good data.
919 /* Changing key state by setting Final = FALSE */
920 dwLen = cTestData[i].buflen;
921 memcpy(pbData, enc_data, cTestData[i].buflen);
922 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
923 ok(result, "%08x\n", GetLastError());
925 /* Restoring key state by decrypting bad_data with Final = TRUE */
926 memcpy(bad_data, enc_data, cTestData[i].buflen);
927 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
928 SetLastError(0xdeadbeef);
929 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
930 ok(!result, "CryptDecrypt should failed!\n");
931 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
932 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
933 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
935 /* Checking key state */
936 dwLen = cTestData[i].buflen;
937 memcpy(pbData, enc_data, cTestData[i].buflen);
938 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
939 ok(result, "%08x\n", GetLastError());
940 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
941 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
942 if((dwLen != cTestData[i].enclen) ||
943 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
945 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
946 printBytes("got",pbData,dwLen);
950 result = CryptDestroyKey(hKey);
951 ok(result, "%08x\n", GetLastError());
954 static void test_3des(void)
956 HCRYPTKEY hKey;
957 BOOL result;
958 DWORD dwLen;
959 unsigned char pbData[16], enc_data[16], bad_data[16];
960 static const BYTE des3[16] = {
961 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
962 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
963 int i;
965 result = derive_key(CALG_3DES, &hKey, 0);
966 if (!result) return;
968 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
970 dwLen = 13;
971 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
972 ok(result, "%08x\n", GetLastError());
974 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
976 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
977 ok(result, "%08x\n", GetLastError());
979 for (i=0; i<4; i++)
981 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
983 dwLen = cTestData[i].enclen;
984 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
985 ok(result, "%08x\n", GetLastError());
986 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
987 memcpy(enc_data, pbData, cTestData[i].buflen);
989 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
990 ok(result, "%08x\n", GetLastError());
991 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
992 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
993 if((dwLen != cTestData[i].enclen) ||
994 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
996 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
997 printBytes("got",pbData,dwLen);
1000 /* Test bad data:
1001 Decrypting a block of bad data with Final = TRUE should restore the
1002 initial state of the key as well as decrypting a block of good data.
1005 /* Changing key state by setting Final = FALSE */
1006 dwLen = cTestData[i].buflen;
1007 memcpy(pbData, enc_data, cTestData[i].buflen);
1008 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
1009 ok(result, "%08x\n", GetLastError());
1011 /* Restoring key state by decrypting bad_data with Final = TRUE */
1012 memcpy(bad_data, enc_data, cTestData[i].buflen);
1013 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
1014 SetLastError(0xdeadbeef);
1015 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
1016 ok(!result, "CryptDecrypt should failed!\n");
1017 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
1018 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1019 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1021 /* Checking key state */
1022 dwLen = cTestData[i].buflen;
1023 memcpy(pbData, enc_data, cTestData[i].buflen);
1024 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1025 ok(result, "%08x\n", GetLastError());
1026 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1027 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1028 if((dwLen != cTestData[i].enclen) ||
1029 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1031 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1032 printBytes("got",pbData,dwLen);
1035 result = CryptDestroyKey(hKey);
1036 ok(result, "%08x\n", GetLastError());
1039 static void test_aes(int keylen)
1041 HCRYPTKEY hKey;
1042 BOOL result;
1043 DWORD dwLen;
1044 unsigned char pbData[16], enc_data[16], bad_data[16];
1045 int i;
1047 switch (keylen)
1049 case 256:
1050 result = derive_key(CALG_AES_256, &hKey, 0);
1051 break;
1052 case 192:
1053 result = derive_key(CALG_AES_192, &hKey, 0);
1054 break;
1055 default:
1056 case 128:
1057 result = derive_key(CALG_AES_128, &hKey, 0);
1058 break;
1060 if (!result) return;
1062 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
1064 /* Does AES provider support salt? */
1065 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1066 ok((!result && GetLastError() == NTE_BAD_KEY) || result /* Win7 */,
1067 "expected NTE_BAD_KEY, got %08x\n", GetLastError());
1068 if (result)
1069 ok(!dwLen, "unexpected salt length %d\n", dwLen);
1071 dwLen = 13;
1072 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
1073 ok(result, "%08x\n", GetLastError());
1075 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1076 ok(result, "%08x\n", GetLastError());
1078 for (i=0; i<4; i++)
1080 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
1082 dwLen = cTestData[i].enclen;
1083 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
1084 ok(result, "%08x\n", GetLastError());
1085 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1086 memcpy(enc_data, pbData, cTestData[i].buflen);
1088 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1089 ok(result, "%08x\n", GetLastError());
1090 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1091 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1092 if((dwLen != cTestData[i].enclen) ||
1093 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1095 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1096 printBytes("got",pbData,dwLen);
1099 /* Test bad data:
1100 Decrypting a block of bad data with Final = TRUE should restore the
1101 initial state of the key as well as decrypting a block of good data.
1104 /* Changing key state by setting Final = FALSE */
1105 dwLen = cTestData[i].buflen;
1106 memcpy(pbData, enc_data, cTestData[i].buflen);
1107 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
1108 ok(result, "%08x\n", GetLastError());
1110 /* Restoring key state by decrypting bad_data with Final = TRUE */
1111 memcpy(bad_data, enc_data, cTestData[i].buflen);
1112 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
1113 SetLastError(0xdeadbeef);
1114 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
1115 ok(!result, "CryptDecrypt should failed!\n");
1116 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
1117 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1118 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1120 /* Checking key state */
1121 dwLen = cTestData[i].buflen;
1122 memcpy(pbData, enc_data, cTestData[i].buflen);
1123 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1124 ok(result, "%08x\n", GetLastError());
1125 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1126 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1127 if((dwLen != cTestData[i].enclen) ||
1128 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1130 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1131 printBytes("got",pbData,dwLen);
1134 result = CryptDestroyKey(hKey);
1135 ok(result, "%08x\n", GetLastError());
1138 static void test_sha2(void)
1140 static const unsigned char sha256hash[32] = {
1141 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
1142 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
1143 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
1144 0x1a, 0x08
1146 static const unsigned char sha384hash[48] = {
1147 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
1148 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
1149 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
1150 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
1151 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
1153 static const unsigned char sha512hash[64] = {
1154 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1155 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1156 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1157 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1158 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1159 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1160 0xb7, 0xf4, 0x81, 0xd4
1162 unsigned char pbData[2048];
1163 BOOL result;
1164 HCRYPTHASH hHash;
1165 BYTE pbHashValue[64];
1166 DWORD hashlen, len;
1167 int i;
1169 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1171 /* SHA-256 hash */
1172 SetLastError(0xdeadbeef);
1173 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1174 if (!result && GetLastError() == NTE_BAD_ALGID) {
1175 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1176 return;
1178 ok(result, "%08x\n", GetLastError());
1179 if (result) {
1180 len = sizeof(DWORD);
1181 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1182 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1184 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1185 ok(result, "%08x\n", GetLastError());
1187 len = 32;
1188 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1189 ok(result, "%08x\n", GetLastError());
1191 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1193 result = CryptDestroyHash(hHash);
1194 ok(result, "%08x\n", GetLastError());
1197 /* SHA-384 hash */
1198 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1199 ok(result, "%08x\n", GetLastError());
1200 if (result) {
1201 len = sizeof(DWORD);
1202 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1203 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1205 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1206 ok(result, "%08x\n", GetLastError());
1208 len = 48;
1209 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1210 ok(result, "%08x\n", GetLastError());
1212 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1214 result = CryptDestroyHash(hHash);
1215 ok(result, "%08x\n", GetLastError());
1218 /* SHA-512 hash */
1219 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1220 ok(result, "%08x\n", GetLastError());
1221 if (result) {
1222 len = sizeof(DWORD);
1223 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1224 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1226 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1227 ok(result, "%08x\n", GetLastError());
1229 len = 64;
1230 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1231 ok(result, "%08x\n", GetLastError());
1233 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1235 result = CryptDestroyHash(hHash);
1236 ok(result, "%08x\n", GetLastError());
1240 static void test_rc2(void)
1242 static const BYTE rc2_40_encrypted[16] = {
1243 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1244 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1245 static const BYTE rc2_128_encrypted[] = {
1246 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
1247 0xb6,0x66 };
1248 HCRYPTHASH hHash;
1249 HCRYPTKEY hKey;
1250 BOOL result;
1251 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
1252 BYTE *pbTemp;
1253 unsigned char pbData[2000], pbHashValue[16];
1254 int i;
1256 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1258 /* MD2 Hashing */
1259 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1260 if (!result) {
1261 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1262 } else {
1263 CRYPT_INTEGER_BLOB salt;
1265 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1266 ok(result, "%08x\n", GetLastError());
1268 dwLen = 16;
1269 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1270 ok(result, "%08x\n", GetLastError());
1272 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1273 ok(result, "%08x\n", GetLastError());
1275 dwLen = sizeof(DWORD);
1276 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1277 ok(result, "%08x\n", GetLastError());
1279 dwMode = CRYPT_MODE_CBC;
1280 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1281 ok(result, "%08x\n", GetLastError());
1283 dwLen = sizeof(DWORD);
1284 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1285 ok(result, "%08x\n", GetLastError());
1287 dwModeBits = 0xdeadbeef;
1288 dwLen = sizeof(DWORD);
1289 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1290 ok(result, "%08x\n", GetLastError());
1291 ok(dwModeBits ==
1292 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1293 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
1294 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1295 " got %08x\n", dwModeBits);
1297 dwLen = sizeof(DWORD);
1298 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1299 ok(result, "%08x\n", GetLastError());
1301 dwLen = sizeof(DWORD);
1302 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1303 ok(result, "%08x\n", GetLastError());
1305 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1306 ok(result, "%08x\n", GetLastError());
1307 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1308 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1309 HeapFree(GetProcessHeap(), 0, pbTemp);
1311 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1312 ok(result, "%08x\n", GetLastError());
1313 /* The default salt length is always 11... */
1314 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1315 /* and the default salt is always empty. */
1316 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1317 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1318 for (i=0; i<dwLen; i++)
1319 ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1320 HeapFree(GetProcessHeap(), 0, pbTemp);
1322 dwLen = sizeof(DWORD);
1323 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1325 result = CryptDestroyHash(hHash);
1326 ok(result, "%08x\n", GetLastError());
1328 dwDataLen = 13;
1329 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1330 ok(result, "%08x\n", GetLastError());
1332 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1334 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1335 ok(result, "%08x\n", GetLastError());
1336 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1337 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1338 HeapFree(GetProcessHeap(), 0, pbTemp);
1340 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1341 ok(result, "%08x\n", GetLastError());
1343 /* Setting the salt also succeeds... */
1344 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1345 ok(result, "setting salt failed: %08x\n", GetLastError());
1346 /* but the resulting salt length is now zero? */
1347 dwLen = 0;
1348 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1349 ok(result, "%08x\n", GetLastError());
1350 ok(dwLen == 0 ||
1351 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1352 "unexpected salt length %d\n", dwLen);
1353 /* What sizes salt can I set? */
1354 salt.pbData = pbData;
1355 for (i=0; i<24; i++)
1357 salt.cbData = i;
1358 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1359 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1360 /* The returned salt length is the same as the set salt length */
1361 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1362 ok(result, "%08x\n", GetLastError());
1363 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1365 salt.cbData = 25;
1366 SetLastError(0xdeadbeef);
1367 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1368 ok(!result ||
1369 broken(result), /* Win9x, WinMe, NT4, W2K */
1370 "%08x\n", GetLastError());
1372 result = CryptDestroyKey(hKey);
1373 ok(result, "%08x\n", GetLastError());
1376 /* Again, but test setting the effective key len */
1377 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1379 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1380 if (!result) {
1381 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1382 } else {
1383 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1384 ok(result, "%08x\n", GetLastError());
1386 dwLen = 16;
1387 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1388 ok(result, "%08x\n", GetLastError());
1390 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1391 ok(result, "%08x\n", GetLastError());
1393 SetLastError(0xdeadbeef);
1394 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1395 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1396 dwKeyLen = 0;
1397 SetLastError(0xdeadbeef);
1398 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1399 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1400 dwKeyLen = 1025;
1401 SetLastError(0xdeadbeef);
1402 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1403 ok(!result, "CryptSetKeyParam failed: %08x\n", GetLastError());
1405 dwLen = sizeof(dwKeyLen);
1406 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1407 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1408 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1409 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1411 dwKeyLen = 128;
1412 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1413 ok(result, "%d\n", GetLastError());
1415 dwLen = sizeof(dwKeyLen);
1416 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1417 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1418 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1419 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1421 result = CryptDestroyHash(hHash);
1422 ok(result, "%08x\n", GetLastError());
1424 dwDataLen = 13;
1425 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1426 ok(result, "%08x\n", GetLastError());
1428 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1429 "RC2 encryption failed!\n");
1431 /* Oddly enough this succeeds, though it should have no effect */
1432 dwKeyLen = 40;
1433 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1434 ok(result, "%d\n", GetLastError());
1436 result = CryptDestroyKey(hKey);
1437 ok(result, "%08x\n", GetLastError());
1441 static void test_rc4(void)
1443 static const BYTE rc4[16] = {
1444 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1445 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1446 BOOL result;
1447 HCRYPTHASH hHash;
1448 HCRYPTKEY hKey;
1449 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1450 unsigned char pbData[2000], *pbTemp;
1451 unsigned char pszBuffer[256];
1452 int i;
1454 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1456 /* MD2 Hashing */
1457 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1458 if (!result) {
1459 /* rsaenh compiled without OpenSSL */
1460 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1461 } else {
1462 CRYPT_INTEGER_BLOB salt;
1464 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1465 ok(result, "%08x\n", GetLastError());
1467 dwLen = 16;
1468 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1469 ok(result, "%08x\n", GetLastError());
1471 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1472 ok(result, "%08x\n", GetLastError());
1474 dwLen = sizeof(DWORD);
1475 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1476 ok(result, "%08x\n", GetLastError());
1478 dwLen = sizeof(DWORD);
1479 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1480 ok(result, "%08x\n", GetLastError());
1482 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1483 ok(result, "%08x\n", GetLastError());
1484 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1485 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1486 HeapFree(GetProcessHeap(), 0, pbTemp);
1488 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1489 ok(result, "%08x\n", GetLastError());
1490 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1491 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1492 HeapFree(GetProcessHeap(), 0, pbTemp);
1494 dwLen = sizeof(DWORD);
1495 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1497 result = CryptDestroyHash(hHash);
1498 ok(result, "%08x\n", GetLastError());
1500 dwDataLen = 16;
1501 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1502 ok(result, "%08x\n", GetLastError());
1503 dwDataLen = 16;
1504 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1505 ok(result, "%08x\n", GetLastError());
1507 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1509 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1510 ok(result, "%08x\n", GetLastError());
1512 /* Setting the salt also succeeds... */
1513 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1514 ok(result, "setting salt failed: %08x\n", GetLastError());
1515 /* but the resulting salt length is now zero? */
1516 dwLen = 0;
1517 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1518 ok(result, "%08x\n", GetLastError());
1519 ok(dwLen == 0 ||
1520 broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1521 "unexpected salt length %d\n", dwLen);
1522 /* What sizes salt can I set? */
1523 salt.pbData = pbData;
1524 for (i=0; i<24; i++)
1526 salt.cbData = i;
1527 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1528 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1529 /* The returned salt length is the same as the set salt length */
1530 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1531 ok(result, "%08x\n", GetLastError());
1532 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1534 salt.cbData = 25;
1535 SetLastError(0xdeadbeef);
1536 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1537 ok(!result ||
1538 broken(result), /* Win9x, WinMe, NT4, W2K */
1539 "%08x\n", GetLastError());
1541 result = CryptDestroyKey(hKey);
1542 ok(result, "%08x\n", GetLastError());
1546 static void test_hmac(void) {
1547 HCRYPTKEY hKey;
1548 HCRYPTHASH hHash;
1549 BOOL result;
1550 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1551 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1552 DWORD dwLen;
1553 BYTE abData[256];
1554 static const BYTE hmac[16] = {
1555 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1556 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1557 int i;
1559 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1561 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1563 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1564 ok(result, "%08x\n", GetLastError());
1565 if (!result) return;
1567 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1568 ok(result, "%08x\n", GetLastError());
1570 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1571 ok(result, "%08x\n", GetLastError());
1573 dwLen = sizeof(abData)/sizeof(BYTE);
1574 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1575 ok(result, "%08x\n", GetLastError());
1577 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1579 result = CryptDestroyHash(hHash);
1580 ok(result, "%08x\n", GetLastError());
1582 result = CryptDestroyKey(hKey);
1583 ok(result, "%08x\n", GetLastError());
1585 /* Provoke errors */
1586 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1587 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1590 static void test_mac(void) {
1591 HCRYPTKEY hKey;
1592 HCRYPTHASH hHash;
1593 BOOL result;
1594 DWORD dwLen;
1595 BYTE abData[256], abEnc[264];
1596 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1597 int i;
1599 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1600 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1602 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1604 dwLen = 256;
1605 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1606 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1608 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1609 ok(result, "%08x\n", GetLastError());
1610 if (!result) return;
1612 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1613 ok(result, "%08x\n", GetLastError());
1615 dwLen = sizeof(abData)/sizeof(BYTE);
1616 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1617 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1619 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1621 result = CryptDestroyHash(hHash);
1622 ok(result, "%08x\n", GetLastError());
1624 result = CryptDestroyKey(hKey);
1625 ok(result, "%08x\n", GetLastError());
1627 /* Provoke errors */
1628 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1630 SetLastError(0xdeadbeef);
1631 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1632 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1633 broken(result), /* Win9x, WinMe, NT4, W2K */
1634 "%08x\n", GetLastError());
1636 result = CryptDestroyKey(hKey);
1637 ok(result, "%08x\n", GetLastError());
1640 static void test_import_private(void)
1642 DWORD dwLen, dwVal;
1643 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1644 BOOL result;
1645 static BYTE abSessionKey[148] = {
1646 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1647 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1648 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1649 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1650 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1651 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1652 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1653 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1654 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1655 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1656 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1657 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1658 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1659 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1660 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1661 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1662 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1663 0x04, 0x8c, 0x49, 0x92
1665 static BYTE abEncryptedMessage[12] = {
1666 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1667 0x1c, 0xfd, 0xde, 0x71
1669 BLOBHEADER *blobHeader = (BLOBHEADER *)abPlainPrivateKey;
1670 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(blobHeader+1);
1672 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1673 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1674 if (!result) {
1675 /* rsaenh compiled without OpenSSL */
1676 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1677 return;
1680 dwLen = (DWORD)sizeof(abSessionKey);
1681 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1682 ok(result, "%08x\n", GetLastError());
1683 if (!result) return;
1685 dwVal = 0xdeadbeef;
1686 dwLen = sizeof(DWORD);
1687 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1688 ok(result, "%08x\n", GetLastError());
1689 ok(dwVal ==
1690 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1691 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1692 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1693 " got %08x\n", dwVal);
1695 dwLen = (DWORD)sizeof(abEncryptedMessage);
1696 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1697 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1698 "%08x, len: %d\n", GetLastError(), dwLen);
1699 CryptDestroyKey(hSessionKey);
1701 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1703 dwLen = (DWORD)sizeof(abSessionKey);
1704 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1705 ok(result, "%08x\n", GetLastError());
1706 CryptDestroyKey(hSessionKey);
1707 if (!result) return;
1709 dwLen = (DWORD)sizeof(abSessionKey);
1710 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1711 ok(result, "%08x\n", GetLastError());
1712 if (!result) return;
1714 CryptDestroyKey(hSessionKey);
1715 CryptDestroyKey(hKeyExchangeKey);
1717 /* Test importing a private key with a buffer that's smaller than the
1718 * actual buffer. The private exponent can be omitted, its length is
1719 * inferred from the passed-in length parameter.
1721 dwLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
1722 rsaPubKey->bitlen / 8 + 5 * rsaPubKey->bitlen / 16;
1723 for (; dwLen < sizeof(abPlainPrivateKey); dwLen++)
1725 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1726 ok(result, "CryptImportKey failed at size %d: %d (%08x)\n", dwLen,
1727 GetLastError(), GetLastError());
1728 if (result)
1729 CryptDestroyKey(hKeyExchangeKey);
1733 static void test_verify_signature(void) {
1734 HCRYPTHASH hHash;
1735 HCRYPTKEY hPubSignKey;
1736 BYTE abData[] = "Wine rocks!";
1737 BOOL result;
1738 BYTE abPubKey[148] = {
1739 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1740 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1741 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1742 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1743 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1744 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1745 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1746 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1747 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1748 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1749 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1750 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1751 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1752 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1753 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1754 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1755 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1756 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1757 0xe1, 0x21, 0x50, 0xac
1759 /* md2 with hash oid */
1760 BYTE abSignatureMD2[128] = {
1761 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1762 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1763 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1764 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1765 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1766 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1767 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1768 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1769 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1770 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1771 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1772 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1773 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1774 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1775 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1776 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1778 /* md2 without hash oid */
1779 BYTE abSignatureMD2NoOID[128] = {
1780 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1781 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1782 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1783 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1784 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1785 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1786 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1787 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1788 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1789 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1790 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1791 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1792 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1793 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1794 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1795 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1797 /* md4 with hash oid */
1798 BYTE abSignatureMD4[128] = {
1799 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1800 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1801 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1802 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1803 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1804 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1805 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1806 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1807 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1808 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1809 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1810 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1811 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1812 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1813 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1814 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1816 /* md4 without hash oid */
1817 BYTE abSignatureMD4NoOID[128] = {
1818 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1819 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1820 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1821 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1822 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1823 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1824 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1825 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1826 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1827 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1828 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1829 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1830 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1831 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1832 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1833 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1835 /* md5 with hash oid */
1836 BYTE abSignatureMD5[128] = {
1837 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1838 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1839 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1840 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1841 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1842 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1843 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1844 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1845 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1846 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1847 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1848 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1849 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1850 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1851 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1852 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1854 /* md5 without hash oid */
1855 BYTE abSignatureMD5NoOID[128] = {
1856 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1857 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1858 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1859 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1860 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1861 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1862 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1863 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1864 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1865 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1866 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1867 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1868 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1869 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1870 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1871 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1873 /* sha with hash oid */
1874 BYTE abSignatureSHA[128] = {
1875 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1876 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1877 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1878 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1879 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1880 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1881 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1882 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1883 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1884 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1885 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1886 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1887 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1888 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1889 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1890 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1892 /* sha without hash oid */
1893 BYTE abSignatureSHANoOID[128] = {
1894 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1895 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1896 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1897 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1898 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1899 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1900 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1901 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1902 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1903 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1904 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1905 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1906 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1907 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1908 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1909 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1912 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1913 ok(result, "%08x\n", GetLastError());
1914 if (!result) return;
1916 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1917 ok(result, "%08x\n", GetLastError());
1918 if (!result) return;
1920 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1921 ok(result, "%08x\n", GetLastError());
1922 if (!result) return;
1924 /*check that a NULL pointer signature is correctly handled*/
1925 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1926 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1927 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1928 if (result) return;
1930 /* check that we get a bad signature error when the signature is too short*/
1931 SetLastError(0xdeadbeef);
1932 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1933 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1934 broken(result), /* Win9x, WinMe, NT4 */
1935 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1937 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1938 ok(result, "%08x\n", GetLastError());
1939 if (!result) return;
1941 /* It seems that CPVerifySignature doesn't care about the OID at all. */
1942 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1943 ok(result, "%08x\n", GetLastError());
1944 if (!result) return;
1946 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1947 ok(result, "%08x\n", GetLastError());
1948 if (!result) return;
1950 CryptDestroyHash(hHash);
1952 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1953 ok(result, "%08x\n", GetLastError());
1954 if (!result) return;
1956 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1957 ok(result, "%08x\n", GetLastError());
1958 if (!result) return;
1960 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1961 ok(result, "%08x\n", GetLastError());
1962 if (!result) return;
1964 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, 0);
1965 ok(result, "%08x\n", GetLastError());
1966 if (!result) return;
1968 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1969 ok(result, "%08x\n", GetLastError());
1970 if (!result) return;
1972 CryptDestroyHash(hHash);
1974 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1975 ok(result, "%08x\n", GetLastError());
1976 if (!result) return;
1978 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1979 ok(result, "%08x\n", GetLastError());
1980 if (!result) return;
1982 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1983 ok(result, "%08x\n", GetLastError());
1984 if (!result) return;
1986 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, 0);
1987 ok(result, "%08x\n", GetLastError());
1988 if (!result) return;
1990 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1991 ok(result, "%08x\n", GetLastError());
1992 if (!result) return;
1994 CryptDestroyHash(hHash);
1996 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1997 ok(result, "%08x\n", GetLastError());
1998 if (!result) return;
2000 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2001 ok(result, "%08x\n", GetLastError());
2002 if (!result) return;
2004 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
2005 ok(result, "%08x\n", GetLastError());
2006 if (!result) return;
2008 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, 0);
2009 ok(result, "%08x\n", GetLastError());
2010 if (!result) return;
2012 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2013 ok(result, "%08x\n", GetLastError());
2014 if (!result) return;
2016 CryptDestroyHash(hHash);
2017 CryptDestroyKey(hPubSignKey);
2020 static void test_rsa_encrypt(void)
2022 HCRYPTKEY hRSAKey;
2023 BYTE abData[2048] = "Wine rocks!";
2024 BOOL result;
2025 DWORD dwVal, dwLen;
2027 /* It is allowed to use the key exchange key for encryption/decryption */
2028 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
2029 ok (result, "%08x\n", GetLastError());
2030 if (!result) return;
2032 dwLen = 12;
2033 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
2034 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
2035 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
2036 dwLen = 12;
2037 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
2038 ok (result, "%08x\n", GetLastError());
2039 if (!result) return;
2041 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
2042 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
2044 dwVal = 0xdeadbeef;
2045 dwLen = sizeof(DWORD);
2046 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2047 ok(result, "%08x\n", GetLastError());
2048 ok(dwVal ==
2049 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2050 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2051 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2052 " got %08x\n", dwVal);
2054 /* An RSA key doesn't support salt */
2055 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
2056 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
2057 "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
2059 /* The key exchange key's public key may be exported.. */
2060 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2061 ok(result, "%08x\n", GetLastError());
2062 /* but its private key may not be. */
2063 SetLastError(0xdeadbeef);
2064 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2065 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
2066 broken(result), /* Win9x/NT4 */
2067 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
2068 /* Setting the permissions of the key exchange key isn't allowed, either. */
2069 dwVal |= CRYPT_EXPORT;
2070 SetLastError(0xdeadbeef);
2071 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2072 ok(!result &&
2073 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
2074 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
2076 CryptDestroyKey(hRSAKey);
2078 /* It is not allowed to use the signature key for encryption/decryption */
2079 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
2080 ok (result, "%08x\n", GetLastError());
2081 if (!result) return;
2083 dwVal = 0xdeadbeef;
2084 dwLen = sizeof(DWORD);
2085 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2086 ok(result, "%08x\n", GetLastError());
2087 ok(dwVal ==
2088 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2089 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2090 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2091 " got %08x\n", dwVal);
2093 /* The signature key's public key may also be exported.. */
2094 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2095 ok(result, "%08x\n", GetLastError());
2096 /* but its private key may not be. */
2097 SetLastError(0xdeadbeef);
2098 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2099 ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
2100 broken(result), /* Win9x/NT4 */
2101 "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
2102 /* Setting the permissions of the signature key isn't allowed, either. */
2103 dwVal |= CRYPT_EXPORT;
2104 SetLastError(0xdeadbeef);
2105 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2106 ok(!result &&
2107 (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
2108 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
2110 dwLen = 12;
2111 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
2112 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
2114 CryptDestroyKey(hRSAKey);
2117 static void test_import_export(void)
2119 DWORD dwLen, dwDataLen, dwVal;
2120 HCRYPTKEY hPublicKey, hPrivKey;
2121 BOOL result;
2122 ALG_ID algID;
2123 BYTE emptyKey[2048], *exported_key;
2124 static BYTE abPlainPublicKey[84] = {
2125 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
2126 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
2127 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
2128 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2129 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2130 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2131 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2132 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2133 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2134 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2135 0x11, 0x11, 0x11, 0x11
2137 static BYTE priv_key_with_high_bit[] = {
2138 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2139 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2140 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2141 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2142 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2143 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2144 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2145 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2146 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2147 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2148 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2149 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2150 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2151 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2152 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2153 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2154 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2155 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2156 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2157 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2158 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2159 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2160 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2161 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2162 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2163 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2164 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2165 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2166 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2167 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2168 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2169 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2170 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2171 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2172 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2173 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2174 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2175 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2176 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2177 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2178 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2179 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2180 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2181 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2182 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2183 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2184 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2185 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2186 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2187 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2188 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2189 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2190 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2191 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2192 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2193 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2194 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2195 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2196 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2197 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2198 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2199 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2200 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2201 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2202 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2203 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2204 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2205 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2206 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2207 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2208 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2209 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2210 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2211 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2212 0xb6, 0x5f, 0x01, 0x5e
2214 static const BYTE expected_exported_priv_key[] = {
2215 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2216 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2217 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2218 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2219 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2220 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2221 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2222 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2223 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2224 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2225 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2226 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2227 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2228 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2229 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2230 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2231 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2232 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2233 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2234 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2235 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2236 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2237 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2238 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2239 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2240 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2241 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2242 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2243 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2244 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2245 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2246 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2247 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2248 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2249 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2250 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2251 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2252 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2253 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2254 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2255 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2256 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2257 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2258 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2259 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2260 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2261 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2262 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2263 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2264 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2265 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2266 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2267 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2268 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2269 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2270 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2271 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2272 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2273 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2274 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2275 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2276 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2277 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2278 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2279 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2280 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2281 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2282 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2283 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2284 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2285 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2286 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2287 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2288 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2289 0xb6, 0x5f, 0x01, 0x5e
2292 dwLen=84;
2293 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2294 ok(result, "failed to import the public key\n");
2296 dwDataLen=sizeof(algID);
2297 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2298 ok(result, "failed to get the KP_ALGID from the imported public key\n");
2299 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2301 dwVal = 0xdeadbeef;
2302 dwDataLen = sizeof(DWORD);
2303 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2304 ok(result, "%08x\n", GetLastError());
2305 ok(dwVal ==
2306 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2307 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2308 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2309 " got %08x\n", dwVal);
2310 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2311 ok(result, "failed to export the fresh imported public key\n");
2312 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2313 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2315 CryptDestroyKey(hPublicKey);
2317 result = CryptImportKey(hProv, priv_key_with_high_bit,
2318 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2319 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2321 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2322 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2323 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2324 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2325 &dwDataLen);
2326 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2328 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2329 dwDataLen);
2330 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2331 "unexpected value\n");
2333 HeapFree(GetProcessHeap(), 0, exported_key);
2335 CryptDestroyKey(hPrivKey);
2338 static void test_import_hmac(void)
2340 /* Test cases from RFC 2202, section 3 */
2341 static const struct rfc2202_test_case {
2342 const char *key;
2343 DWORD key_len;
2344 const char *data;
2345 const DWORD data_len;
2346 const char *digest;
2347 } cases[] = {
2348 { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2349 "\x0b\x0b\x0b\x0b", 20,
2350 "Hi There", 8,
2351 "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2352 "\xf1\x46\xbe\x00" },
2353 { "Jefe", 4,
2354 "what do ya want for nothing?", 28,
2355 "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2356 "\x25\x9a\x7c\x79" },
2357 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2358 "\xaa\xaa\xaa\xaa", 20,
2359 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2360 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2361 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2362 "\xdd\xdd", 50,
2363 "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2364 "\x63\xf1\x75\xd3" },
2365 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2366 "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2367 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2368 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2369 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2370 "\xcd\xcd", 50,
2371 "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2372 "\x2d\x72\x35\xda" },
2373 { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2374 "\x0c\x0c\x0c\x0c", 20,
2375 "Test With Truncation", 20,
2376 "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2377 "\x4a\x9a\x5a\x04" },
2378 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2379 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2380 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
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",
2384 "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2385 "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2386 "\xed\x40\x21\x12" },
2387 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2388 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2389 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2390 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2391 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2393 "Test Using Larger Than Block-Size Key and Larger "
2394 "Than One Block-Size Data", 73,
2395 "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2396 "\xbb\xff\x1a\x91" }
2398 DWORD i;
2400 for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++)
2402 const struct rfc2202_test_case *test_case = &cases[i];
2403 DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2404 BYTE *blob = HeapAlloc(GetProcessHeap(), 0, size);
2406 if (blob)
2408 BLOBHEADER *header = (BLOBHEADER *)blob;
2409 DWORD *key_len = (DWORD *)(header + 1);
2410 BYTE *key_bytes = (BYTE *)(key_len + 1);
2411 BOOL result;
2412 HCRYPTKEY key;
2414 header->bType = PLAINTEXTKEYBLOB;
2415 header->bVersion = CUR_BLOB_VERSION;
2416 header->reserved = 0;
2417 header->aiKeyAlg = CALG_RC2;
2418 *key_len = test_case->key_len;
2419 memcpy(key_bytes, test_case->key, *key_len);
2420 result = CryptImportKey(hProv, blob, size, 0, CRYPT_IPSEC_HMAC_KEY, &key);
2421 ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
2422 if (result)
2424 HCRYPTHASH hash;
2425 HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2426 BYTE digest[20];
2427 DWORD digest_size;
2429 result = CryptCreateHash(hProv, CALG_HMAC, key, 0, &hash);
2430 ok(result, "CryptCreateHash failed on test case %d: %08x\n", i, GetLastError());
2431 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2432 ok(result, "CryptSetHashParam failed on test case %d: %08x\n", i, GetLastError());
2433 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2434 ok(result, "CryptHashData failed on test case %d: %08x\n", i, GetLastError());
2435 digest_size = sizeof(digest);
2436 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2437 ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
2438 ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected value on test case %d\n", i);
2439 CryptDestroyHash(hash);
2440 CryptDestroyKey(key);
2442 HeapFree(GetProcessHeap(), 0, blob);
2447 static void test_schannel_provider(void)
2449 HCRYPTPROV hProv;
2450 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2451 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2452 BOOL result;
2453 DWORD dwLen;
2454 SCHANNEL_ALG saSChannelAlg;
2455 CRYPT_DATA_BLOB data_blob;
2456 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2457 BYTE abTLS1Master[140] = {
2458 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2459 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2460 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2461 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2462 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2463 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2464 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2465 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2466 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2467 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2468 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2469 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2470 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2471 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2472 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2473 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2474 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2475 0xd3, 0x1e, 0x82, 0xb3
2477 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2478 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2479 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2480 BYTE abClientFinished[16] = "client finished";
2481 BYTE abData[16] = "Wine rocks!";
2482 BYTE abMD5Hash[16];
2483 static const BYTE abEncryptedData[16] = {
2484 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2485 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2487 static const BYTE abPRF[16] = {
2488 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2489 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2491 static const BYTE abMD5[16] = {
2492 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2493 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2496 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2497 if (!result)
2499 win_skip("no PROV_RSA_SCHANNEL support\n");
2500 return;
2502 ok (result, "%08x\n", GetLastError());
2503 if (result)
2504 CryptReleaseContext(hProv, 0);
2506 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2507 ok (result, "%08x\n", GetLastError());
2508 if (!result) return;
2510 /* To get deterministic results, we import the TLS1 master secret (which
2511 * is typically generated from a random generator). Therefore, we need
2512 * an RSA key. */
2513 dwLen = (DWORD)sizeof(abPlainPrivateKey);
2514 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2515 ok (result, "%08x\n", GetLastError());
2516 if (!result) return;
2518 dwLen = (DWORD)sizeof(abTLS1Master);
2519 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2520 ok (result, "%08x\n", GetLastError());
2521 if (!result) return;
2523 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2524 * (Keys can only be derived from hashes, not from other keys.)
2525 * The hash can't be created yet because the key doesn't have the client
2526 * random or server random set.
2528 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2529 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER,
2530 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2532 /* Setting the TLS1 client and server random parameters, as well as the
2533 * MAC and encryption algorithm parameters. */
2534 data_blob.cbData = 33;
2535 data_blob.pbData = abClientSecret;
2536 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2537 ok (result, "%08x\n", GetLastError());
2538 if (!result) return;
2540 data_blob.cbData = 33;
2541 data_blob.pbData = abServerSecret;
2542 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2543 ok (result, "%08x\n", GetLastError());
2544 if (!result) return;
2546 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2547 ok (result, "%08x\n", GetLastError());
2548 if (!result) return;
2550 /* Deriving the server write encryption key from the master hash can't
2551 * succeed before the encryption key algorithm is set.
2553 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2554 ok (!result && GetLastError() == NTE_BAD_FLAGS,
2555 "expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2557 CryptDestroyHash(hMasterHash);
2559 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2560 saSChannelAlg.Algid = CALG_DES;
2561 saSChannelAlg.cBits = 64;
2562 saSChannelAlg.dwFlags = 0;
2563 saSChannelAlg.dwReserved = 0;
2564 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2565 ok (result, "%08x\n", GetLastError());
2566 if (!result) return;
2568 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2569 saSChannelAlg.Algid = CALG_MD5;
2570 saSChannelAlg.cBits = 128;
2571 saSChannelAlg.dwFlags = 0;
2572 saSChannelAlg.dwReserved = 0;
2573 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2574 ok (result, "%08x\n", GetLastError());
2575 if (!result) return;
2577 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2578 ok (result, "%08x\n", GetLastError());
2579 if (!result) return;
2581 /* Deriving the server write encryption key from the master hash */
2582 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2583 ok (result, "%08x\n", GetLastError());
2584 if (!result) return;
2586 /* Encrypting some data with the server write encryption key and checking the result. */
2587 dwLen = 12;
2588 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2589 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2591 /* Second test case: Test the TLS1 pseudo random number function. */
2592 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2593 ok (result, "%08x\n", GetLastError());
2594 if (!result) return;
2596 /* Set the label and seed parameters for the random number function */
2597 data_blob.cbData = 36;
2598 data_blob.pbData = abHashedHandshakes;
2599 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2600 ok (result, "%08x\n", GetLastError());
2601 if (!result) return;
2603 data_blob.cbData = 15;
2604 data_blob.pbData = abClientFinished;
2605 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2606 ok (result, "%08x\n", GetLastError());
2607 if (!result) return;
2609 /* Generate some pseudo random bytes and check if they are correct. */
2610 dwLen = (DWORD)sizeof(abData);
2611 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2612 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2613 "%08x\n", GetLastError());
2615 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2616 * Hash some data with the HMAC. Compare results. */
2617 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2618 ok (result, "%08x\n", GetLastError());
2619 if (!result) return;
2621 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2622 ok (result, "%08x\n", GetLastError());
2623 if (!result) return;
2625 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2626 ok (result, "%08x\n", GetLastError());
2627 if (!result) return;
2629 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2630 ok (result, "%08x\n", GetLastError());
2631 if (!result) return;
2633 dwLen = (DWORD)sizeof(abMD5Hash);
2634 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2635 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2637 CryptDestroyHash(hHMAC);
2638 CryptDestroyHash(hTLS1PRF);
2639 CryptDestroyHash(hMasterHash);
2640 CryptDestroyKey(hServerWriteMACKey);
2641 CryptDestroyKey(hServerWriteKey);
2642 CryptDestroyKey(hRSAKey);
2643 CryptDestroyKey(hMasterSecret);
2644 CryptReleaseContext(hProv, 0);
2645 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2648 /* Test that a key can be used to encrypt data and exported, and that, when
2649 * the exported key is imported again, can be used to decrypt the original
2650 * data again.
2652 static void test_rsa_round_trip(void)
2654 static const char test_string[] = "Well this is a fine how-do-you-do.";
2655 HCRYPTPROV prov;
2656 HCRYPTKEY signKey, keyExchangeKey;
2657 BOOL result;
2658 BYTE data[256], *exportedKey;
2659 DWORD dataLen, keyLen;
2661 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2662 CRYPT_DELETEKEYSET);
2664 /* Generate a new key... */
2665 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2666 CRYPT_NEWKEYSET);
2667 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2668 result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2669 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2670 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2671 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2672 /* encrypt some data with it... */
2673 memcpy(data, test_string, strlen(test_string) + 1);
2674 dataLen = strlen(test_string) + 1;
2675 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2676 sizeof(data));
2677 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2678 broken(GetLastError() == NTE_PERM /* NT4 */),
2679 "CryptEncrypt failed: %08x\n", GetLastError());
2680 /* export the key... */
2681 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2682 &keyLen);
2683 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2684 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2685 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2686 &keyLen);
2687 ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2688 /* destroy the key... */
2689 CryptDestroyKey(keyExchangeKey);
2690 CryptDestroyKey(signKey);
2691 /* import the key again... */
2692 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2693 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2694 HeapFree(GetProcessHeap(), 0, exportedKey);
2695 /* and decrypt the data encrypted with the original key with the imported
2696 * key.
2698 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2699 ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2700 broken(GetLastError() == NTE_PERM /* NT4 */),
2701 "CryptDecrypt failed: %08x\n", GetLastError());
2702 if (result)
2704 ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2705 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2707 CryptDestroyKey(keyExchangeKey);
2708 CryptReleaseContext(prov, 0);
2710 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2711 CRYPT_DELETEKEYSET);
2714 static void test_enum_container(void)
2716 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2717 DWORD dwBufferLen;
2718 BOOL result, fFound = FALSE;
2720 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2721 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2722 SetLastError(0xdeadbeef);
2723 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2724 ok (result, "%08x\n", GetLastError());
2725 ok (dwBufferLen == MAX_PATH + 1 ||
2726 broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2727 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2729 /* If the result fits into abContainerName dwBufferLen is left untouched */
2730 dwBufferLen = (DWORD)sizeof(abContainerName);
2731 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2732 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2734 /* We only check, if the currently open 'winetest' container is among the enumerated. */
2735 do {
2736 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2737 dwBufferLen = (DWORD)sizeof(abContainerName);
2738 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2740 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2743 static BYTE signBlob[] = {
2744 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2745 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2746 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2747 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2748 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2749 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2750 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2751 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2752 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2753 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2754 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2755 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2756 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2757 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2758 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2759 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2760 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2761 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2762 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2763 0xb6,0x85,0x86,0x07 };
2765 static void test_null_provider(void)
2767 HCRYPTPROV prov;
2768 HCRYPTKEY key;
2769 BOOL result;
2770 DWORD keySpec, dataLen,dwParam;
2771 char szName[MAX_PATH];
2773 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2774 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2775 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2776 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2777 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2778 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2779 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2780 CRYPT_DELETEKEYSET);
2781 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2782 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2783 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2784 CRYPT_DELETEKEYSET);
2785 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2786 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2787 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2788 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2789 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2791 /* Delete the default container. */
2792 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2793 /* Once you've deleted the default container you can't open it as if it
2794 * already exists.
2796 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2797 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2798 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2799 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2800 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2801 CRYPT_VERIFYCONTEXT);
2802 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2803 if (!result) return;
2804 dataLen = sizeof(keySpec);
2805 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2806 if (result)
2807 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2808 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2809 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2810 * supported, you can't get the keys from this container.
2812 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2813 ok(!result && GetLastError() == NTE_NO_KEY,
2814 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2815 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2816 ok(!result && GetLastError() == NTE_NO_KEY,
2817 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2818 result = CryptReleaseContext(prov, 0);
2819 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2820 /* You can create a new default container. */
2821 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2822 CRYPT_NEWKEYSET);
2823 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2824 /* But you still can't get the keys (until one's been generated.) */
2825 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2826 ok(!result && GetLastError() == NTE_NO_KEY,
2827 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2828 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2829 ok(!result && GetLastError() == NTE_NO_KEY,
2830 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2831 CryptReleaseContext(prov, 0);
2832 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2834 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2835 CRYPT_DELETEKEYSET);
2836 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2837 ok(!result && GetLastError() == NTE_BAD_KEYSET,
2838 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2839 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2840 CRYPT_VERIFYCONTEXT);
2841 ok(!result && GetLastError() == NTE_BAD_FLAGS,
2842 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2843 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2844 CRYPT_NEWKEYSET);
2845 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2846 if (!result) return;
2847 /* Test provider parameters getter */
2848 dataLen = sizeof(dwParam);
2849 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2850 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2851 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2852 dataLen = sizeof(dwParam);
2853 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2854 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2855 "Expected 0, got 0x%08X\n",dwParam);
2856 dataLen = sizeof(dwParam);
2857 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2858 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2859 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2860 dataLen = sizeof(keySpec);
2861 SetLastError(0xdeadbeef);
2862 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2863 if (!result && GetLastError() == NTE_BAD_TYPE)
2864 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2865 else
2866 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2867 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2868 /* PP_CONTAINER parameter */
2869 dataLen = sizeof(szName);
2870 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2871 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2872 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2873 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2874 /* PP_UNIQUE_CONTAINER parameter */
2875 dataLen = sizeof(szName);
2876 SetLastError(0xdeadbeef);
2877 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2878 if (!result && GetLastError() == NTE_BAD_TYPE)
2880 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2882 else
2884 char container[MAX_PATH];
2886 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2887 uniquecontainer(container);
2888 todo_wine
2890 ok(dataLen == strlen(container)+1 ||
2891 broken(dataLen == strlen(szContainer)+1) /* WinME */,
2892 "Expected a param length of 70, got %d\n", dataLen);
2893 ok(!strcmp(container, szName) ||
2894 broken(!strcmp(szName, szContainer)) /* WinME */,
2895 "Wrong container name : %s\n", szName);
2898 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2899 ok(!result && GetLastError() == NTE_NO_KEY,
2900 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2901 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2902 ok(!result && GetLastError() == NTE_NO_KEY,
2903 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2905 /* Importing a key exchange blob.. */
2906 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2907 0, 0, &key);
2908 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2909 CryptDestroyKey(key);
2910 /* allows access to the key exchange key.. */
2911 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2912 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2913 CryptDestroyKey(key);
2914 /* but not to the private key. */
2915 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2916 ok(!result && GetLastError() == NTE_NO_KEY,
2917 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2918 CryptReleaseContext(prov, 0);
2919 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2920 CRYPT_DELETEKEYSET);
2922 /* Whereas importing a sign blob.. */
2923 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2924 CRYPT_NEWKEYSET);
2925 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2926 if (!result) return;
2927 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2928 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2929 CryptDestroyKey(key);
2930 /* doesn't allow access to the key exchange key.. */
2931 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2932 ok(!result && GetLastError() == NTE_NO_KEY,
2933 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2934 /* but does to the private key. */
2935 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2936 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2937 CryptDestroyKey(key);
2938 CryptReleaseContext(prov, 0);
2940 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2941 CRYPT_DELETEKEYSET);
2943 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2944 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2945 CRYPT_NEWKEYSET);
2946 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2947 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2948 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2949 CryptDestroyKey(key);
2950 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2951 ok(!result, "expected CryptGetUserKey to fail\n");
2952 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2953 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2954 CryptDestroyKey(key);
2955 CryptReleaseContext(prov, 0);
2957 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2958 CRYPT_DELETEKEYSET);
2960 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2961 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2962 CRYPT_NEWKEYSET);
2963 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2964 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2965 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2966 CryptDestroyKey(key);
2967 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2968 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2969 CryptDestroyKey(key);
2970 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2971 ok(!result, "expected CryptGetUserKey to fail\n");
2972 CryptReleaseContext(prov, 0);
2974 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2975 CRYPT_DELETEKEYSET);
2977 /* test for the bug in accessing the user key in a container
2979 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2980 CRYPT_NEWKEYSET);
2981 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2982 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2983 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2984 CryptDestroyKey(key);
2985 CryptReleaseContext(prov,0);
2986 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2987 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2988 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2989 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2990 CryptDestroyKey(key);
2991 CryptReleaseContext(prov, 0);
2993 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2994 CRYPT_DELETEKEYSET);
2996 /* test the machine key set */
2997 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2998 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2999 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
3000 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
3001 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
3002 CryptReleaseContext(prov, 0);
3003 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
3004 CRYPT_MACHINE_KEYSET);
3005 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
3006 CryptReleaseContext(prov,0);
3007 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
3008 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
3009 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
3010 GetLastError());
3011 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
3012 CRYPT_MACHINE_KEYSET);
3013 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
3014 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3018 static void test_key_permissions(void)
3020 HCRYPTKEY hKey1, hKey2;
3021 DWORD dwVal, dwLen;
3022 BOOL result;
3024 /* Create keys that are exportable */
3025 if (!init_base_environment(CRYPT_EXPORTABLE))
3026 return;
3028 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
3029 ok (result, "%08x\n", GetLastError());
3030 if (!result) return;
3032 dwVal = 0xdeadbeef;
3033 dwLen = sizeof(DWORD);
3034 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3035 ok(result, "%08x\n", GetLastError());
3036 ok(dwVal ==
3037 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
3038 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3039 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3040 " got %08x\n", dwVal);
3042 /* The key exchange key's public key may be exported.. */
3043 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
3044 ok(result, "%08x\n", GetLastError());
3045 /* and its private key may be too. */
3046 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
3047 ok(result, "%08x\n", GetLastError());
3048 /* Turning off the key's export permissions is "allowed".. */
3049 dwVal &= ~CRYPT_EXPORT;
3050 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
3051 ok(result ||
3052 broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
3053 broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
3054 "%08x\n", GetLastError());
3055 /* but it has no effect. */
3056 dwVal = 0xdeadbeef;
3057 dwLen = sizeof(DWORD);
3058 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3059 ok(result, "%08x\n", GetLastError());
3060 ok(dwVal ==
3061 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
3062 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3063 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3064 " got %08x\n", dwVal);
3065 /* Thus, changing the export flag of the key doesn't affect whether the key
3066 * may be exported.
3068 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
3069 ok(result, "%08x\n", GetLastError());
3071 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
3072 ok (result, "%08x\n", GetLastError());
3074 /* A subsequent get of the same key, into a different handle, also doesn't
3075 * show that the permissions have been changed.
3077 dwVal = 0xdeadbeef;
3078 dwLen = sizeof(DWORD);
3079 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3080 ok(result, "%08x\n", GetLastError());
3081 ok(dwVal ==
3082 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
3083 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3084 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3085 " got %08x\n", dwVal);
3087 CryptDestroyKey(hKey2);
3088 CryptDestroyKey(hKey1);
3090 clean_up_base_environment();
3093 static void test_key_initialization(void)
3095 DWORD dwLen;
3096 HCRYPTPROV prov1, prov2;
3097 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
3098 BOOL result;
3099 static BYTE abSessionKey[148] = {
3100 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
3101 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
3102 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
3103 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
3104 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
3105 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
3106 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
3107 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
3108 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
3109 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
3110 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
3111 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
3112 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
3113 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
3114 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
3115 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
3116 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
3117 0x04, 0x8c, 0x49, 0x92
3120 /* Like init_base_environment, but doesn't generate new keys, as they'll
3121 * be imported instead.
3123 if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
3125 result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
3126 CRYPT_NEWKEYSET);
3127 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
3129 dwLen = (DWORD)sizeof(abPlainPrivateKey);
3130 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
3131 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3133 dwLen = (DWORD)sizeof(abSessionKey);
3134 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
3135 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3137 /* Once the key has been imported, subsequently acquiring a context with
3138 * the same name will allow retrieving the key.
3140 result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
3141 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
3142 result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
3143 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3144 if (result) CryptDestroyKey(hKey);
3145 CryptReleaseContext(prov2, 0);
3147 CryptDestroyKey(hSessionKey);
3148 CryptDestroyKey(hKeyExchangeKey);
3149 CryptReleaseContext(prov1, 0);
3150 CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
3151 CRYPT_DELETEKEYSET);
3154 START_TEST(rsaenh)
3156 if (!init_base_environment(0))
3157 return;
3158 test_prov();
3159 test_gen_random();
3160 test_hashes();
3161 test_rc4();
3162 test_rc2();
3163 test_des();
3164 test_3des112();
3165 test_3des();
3166 test_hmac();
3167 test_mac();
3168 test_block_cipher_modes();
3169 test_import_private();
3170 test_verify_signature();
3171 test_rsa_encrypt();
3172 test_import_export();
3173 test_import_hmac();
3174 test_enum_container();
3175 clean_up_base_environment();
3176 test_key_permissions();
3177 test_key_initialization();
3178 test_schannel_provider();
3179 test_null_provider();
3180 test_rsa_round_trip();
3181 if (!init_aes_environment())
3182 return;
3183 test_aes(128);
3184 test_aes(192);
3185 test_aes(256);
3186 test_sha2();
3187 clean_up_aes_environment();