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