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