rsaenh: Use the correct registry key in RSAENH_CPAcquireContext.
[wine/wine64.git] / dlls / rsaenh / tests / rsaenh.c
blobb51a0a526ee205760f99c00f3be6a09a20b017cb
1 /*
2 * Unit tests for rsaenh functions
4 * Copyright (c) 2004 Michael Jung
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <string.h>
22 #include <stdio.h>
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "wincrypt.h"
29 static HCRYPTPROV hProv;
30 static const char szContainer[] = "winetest";
31 static const unsigned char pbData[] = "Wine rocks totally!";
32 static const char szProvider[] = MS_ENHANCED_PROV_A;
34 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
37 static void trace_hex(BYTE *pbData, DWORD dwLen) {
38 char szTemp[256];
39 DWORD i, j;
41 for (i = 0; i < dwLen-7; i+=8) {
42 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
43 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
44 pbData[i+6], pbData[i+7]);
45 trace(szTemp);
47 for (j=0; i<dwLen; j++,i++) {
48 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
50 trace(szTemp);
54 static int init_environment(void)
56 HCRYPTKEY hKey;
57 BOOL result;
59 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
61 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
63 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
64 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
66 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
68 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
69 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
70 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
71 CRYPT_NEWKEYSET);
72 ok(result, "%08x\n", GetLastError());
73 if (!result) return 0;
74 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
75 ok(result, "%08x\n", GetLastError());
76 if (result) CryptDestroyKey(hKey);
77 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
78 ok(result, "%08x\n", GetLastError());
79 if (result) CryptDestroyKey(hKey);
81 return 1;
84 static void clean_up_environment(void)
86 BOOL result;
88 result = CryptReleaseContext(hProv, 1);
89 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
91 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
94 static void test_prov(void)
96 BOOL result;
97 DWORD dwLen, dwInc;
99 dwLen = (DWORD)sizeof(DWORD);
100 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
101 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
103 dwLen = (DWORD)sizeof(DWORD);
104 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
105 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
108 static void test_gen_random(void)
110 BOOL result;
111 BYTE rnd1[16], rnd2[16];
113 memset(rnd1, 0, sizeof(rnd1));
114 memset(rnd2, 0, sizeof(rnd2));
116 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
117 if (!result && GetLastError() == NTE_FAIL) {
118 /* rsaenh compiled without OpenSSL */
119 return;
122 ok(result, "%08x\n", GetLastError());
124 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
125 ok(result, "%08x\n", GetLastError());
127 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
130 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
132 HCRYPTHASH hHash;
133 BOOL result;
134 unsigned char pbData[2000];
135 int i;
137 *phKey = (HCRYPTKEY)NULL;
138 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
139 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
140 if (!result) {
141 /* rsaenh compiled without OpenSSL */
142 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
143 return FALSE;
145 ok(result, "%08x\n", GetLastError());
146 if (!result) return FALSE;
147 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
148 ok(result, "%08x\n", GetLastError());
149 if (!result) return FALSE;
150 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
151 ok(result, "%08x\n", GetLastError());
152 if (!result) return FALSE;
153 len = 2000;
154 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
155 ok(result, "%08x\n", GetLastError());
156 CryptDestroyHash(hHash);
157 return TRUE;
160 static void test_hashes(void)
162 static const unsigned char md2hash[16] = {
163 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
164 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
165 static const unsigned char md4hash[16] = {
166 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
167 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
168 static const unsigned char md5hash[16] = {
169 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
170 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
171 static const unsigned char sha1hash[20] = {
172 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
173 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
174 unsigned char pbData[2048];
175 BOOL result;
176 HCRYPTHASH hHash, hHashClone;
177 BYTE pbHashValue[36];
178 DWORD hashlen, len;
179 int i;
181 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
183 /* MD2 Hashing */
184 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
185 if (!result) {
186 /* rsaenh compiled without OpenSSL */
187 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
188 } else {
189 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
190 ok(result, "%08x\n", GetLastError());
192 len = sizeof(DWORD);
193 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
194 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
196 len = 16;
197 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
198 ok(result, "%08x\n", GetLastError());
200 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
202 result = CryptDestroyHash(hHash);
203 ok(result, "%08x\n", GetLastError());
206 /* MD4 Hashing */
207 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
208 ok(result, "%08x\n", GetLastError());
210 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
211 ok(result, "%08x\n", GetLastError());
213 len = sizeof(DWORD);
214 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
215 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
217 len = 16;
218 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
219 ok(result, "%08x\n", GetLastError());
221 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
223 result = CryptDestroyHash(hHash);
224 ok(result, "%08x\n", GetLastError());
226 /* MD5 Hashing */
227 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
228 ok(result, "%08x\n", GetLastError());
230 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
231 ok(result, "%08x\n", GetLastError());
233 len = sizeof(DWORD);
234 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
235 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
237 len = 16;
238 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
239 ok(result, "%08x\n", GetLastError());
241 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
243 result = CryptDestroyHash(hHash);
244 ok(result, "%08x\n", GetLastError());
246 /* SHA1 Hashing */
247 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
248 ok(result, "%08x\n", GetLastError());
250 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
251 ok(result, "%08x\n", GetLastError());
253 if(pCryptDuplicateHash) {
254 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
255 ok(result, "%08x\n", GetLastError());
257 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
258 ok(result, "%08x\n", GetLastError());
260 len = sizeof(DWORD);
261 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
262 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
264 len = 20;
265 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
266 ok(result, "%08x\n", GetLastError());
268 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
270 result = CryptDestroyHash(hHashClone);
271 ok(result, "%08x\n", GetLastError());
274 result = CryptDestroyHash(hHash);
275 ok(result, "%08x\n", GetLastError());
278 static void test_block_cipher_modes(void)
280 static const BYTE plain[23] = {
281 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
282 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
283 static const BYTE ecb[24] = {
284 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
285 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
286 static const BYTE cbc[24] = {
287 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
288 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
289 static const BYTE cfb[24] = {
290 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
291 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
292 HCRYPTKEY hKey;
293 BOOL result;
294 BYTE abData[24];
295 DWORD dwMode, dwLen;
297 result = derive_key(CALG_RC2, &hKey, 40);
298 if (!result) return;
300 memcpy(abData, plain, sizeof(abData));
302 dwMode = CRYPT_MODE_ECB;
303 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
304 ok(result, "%08x\n", GetLastError());
306 dwLen = 23;
307 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
308 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
309 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
311 SetLastError(ERROR_SUCCESS);
312 dwLen = 23;
313 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
314 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
315 "%08x, dwLen: %d\n", GetLastError(), dwLen);
317 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
318 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
319 "%08x, dwLen: %d\n", GetLastError(), dwLen);
321 dwMode = CRYPT_MODE_CBC;
322 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
323 ok(result, "%08x\n", GetLastError());
325 dwLen = 23;
326 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
327 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
328 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
330 dwLen = 23;
331 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
332 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
333 "%08x, dwLen: %d\n", GetLastError(), dwLen);
335 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
336 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
337 "%08x, dwLen: %d\n", GetLastError(), dwLen);
339 dwMode = CRYPT_MODE_CFB;
340 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
341 ok(result, "%08x\n", GetLastError());
343 dwLen = 16;
344 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
345 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
347 dwLen = 7;
348 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
349 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
350 "%08x, dwLen: %d\n", GetLastError(), dwLen);
352 dwLen = 8;
353 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
354 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
356 dwLen = 16;
357 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
358 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
359 "%08x, dwLen: %d\n", GetLastError(), dwLen);
361 dwMode = CRYPT_MODE_OFB;
362 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
363 ok(result, "%08x\n", GetLastError());
365 dwLen = 23;
366 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
367 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
370 static void test_3des112(void)
372 HCRYPTKEY hKey;
373 BOOL result;
374 DWORD dwLen;
375 unsigned char pbData[16];
376 int i;
378 result = derive_key(CALG_3DES_112, &hKey, 0);
379 if (!result) {
380 /* rsaenh compiled without OpenSSL */
381 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
382 return;
385 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
387 dwLen = 13;
388 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
389 ok(result, "%08x\n", GetLastError());
391 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
392 ok(result, "%08x\n", GetLastError());
394 result = CryptDestroyKey(hKey);
395 ok(result, "%08x\n", GetLastError());
398 static void test_des(void)
400 HCRYPTKEY hKey;
401 BOOL result;
402 DWORD dwLen, dwMode;
403 unsigned char pbData[16];
404 int i;
406 result = derive_key(CALG_DES, &hKey, 56);
407 if (!result) {
408 /* rsaenh compiled without OpenSSL */
409 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
410 return;
413 dwMode = CRYPT_MODE_ECB;
414 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
415 ok(result, "%08x\n", GetLastError());
417 dwLen = sizeof(DWORD);
418 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
419 ok(result, "%08x\n", GetLastError());
421 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
423 dwLen = 13;
424 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
425 ok(result, "%08x\n", GetLastError());
427 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
428 ok(result, "%08x\n", GetLastError());
430 result = CryptDestroyKey(hKey);
431 ok(result, "%08x\n", GetLastError());
434 static void test_3des(void)
436 HCRYPTKEY hKey;
437 BOOL result;
438 DWORD dwLen;
439 unsigned char pbData[16];
440 static const BYTE des3[16] = {
441 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
442 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
443 int i;
445 result = derive_key(CALG_3DES, &hKey, 0);
446 if (!result) return;
448 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
450 dwLen = 13;
451 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
452 ok(result, "%08x\n", GetLastError());
454 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
456 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
457 ok(result, "%08x\n", GetLastError());
459 result = CryptDestroyKey(hKey);
460 ok(result, "%08x\n", GetLastError());
463 static void test_rc2(void)
465 static const BYTE rc2encrypted[16] = {
466 0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
467 0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
468 HCRYPTHASH hHash;
469 HCRYPTKEY hKey;
470 BOOL result;
471 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
472 BYTE *pbTemp;
473 unsigned char pbData[2000], pbHashValue[16];
474 int i;
476 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
478 /* MD2 Hashing */
479 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
480 if (!result) {
481 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
482 } else {
483 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
484 ok(result, "%08x\n", GetLastError());
486 dwLen = 16;
487 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
488 ok(result, "%08x\n", GetLastError());
490 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
491 ok(result, "%08x\n", GetLastError());
493 dwLen = sizeof(DWORD);
494 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
495 ok(result, "%08x\n", GetLastError());
497 dwMode = CRYPT_MODE_CBC;
498 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
499 ok(result, "%08x\n", GetLastError());
501 dwLen = sizeof(DWORD);
502 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
503 ok(result, "%08x\n", GetLastError());
505 dwLen = sizeof(DWORD);
506 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
507 ok(result, "%08x\n", GetLastError());
509 dwLen = sizeof(DWORD);
510 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
511 ok(result, "%08x\n", GetLastError());
513 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
514 ok(result, "%08x\n", GetLastError());
515 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
516 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
517 HeapFree(GetProcessHeap(), 0, pbTemp);
519 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
520 ok(result, "%08x\n", GetLastError());
521 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
522 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
523 HeapFree(GetProcessHeap(), 0, pbTemp);
525 dwLen = sizeof(DWORD);
526 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
528 result = CryptDestroyHash(hHash);
529 ok(result, "%08x\n", GetLastError());
531 dwDataLen = 13;
532 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
533 ok(result, "%08x\n", GetLastError());
535 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
537 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
538 ok(result, "%08x\n", GetLastError());
539 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
540 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
541 HeapFree(GetProcessHeap(), 0, pbTemp);
543 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
544 ok(result, "%08x\n", GetLastError());
546 result = CryptDestroyKey(hKey);
547 ok(result, "%08x\n", GetLastError());
551 static void test_rc4(void)
553 static const BYTE rc4[16] = {
554 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
555 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
556 BOOL result;
557 HCRYPTHASH hHash;
558 HCRYPTKEY hKey;
559 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
560 unsigned char pbData[2000], *pbTemp;
561 unsigned char pszBuffer[256];
562 int i;
564 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
566 /* MD2 Hashing */
567 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
568 if (!result) {
569 /* rsaenh compiled without OpenSSL */
570 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
571 } else {
572 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
573 ok(result, "%08x\n", GetLastError());
575 dwLen = 16;
576 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
577 ok(result, "%08x\n", GetLastError());
579 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
580 ok(result, "%08x\n", GetLastError());
582 dwLen = sizeof(DWORD);
583 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
584 ok(result, "%08x\n", GetLastError());
586 dwLen = sizeof(DWORD);
587 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
588 ok(result, "%08x\n", GetLastError());
590 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
591 ok(result, "%08x\n", GetLastError());
592 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
593 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
594 HeapFree(GetProcessHeap(), 0, pbTemp);
596 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
597 ok(result, "%08x\n", GetLastError());
598 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
599 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
600 HeapFree(GetProcessHeap(), 0, pbTemp);
602 dwLen = sizeof(DWORD);
603 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
605 result = CryptDestroyHash(hHash);
606 ok(result, "%08x\n", GetLastError());
608 dwDataLen = 16;
609 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
610 ok(result, "%08x\n", GetLastError());
611 dwDataLen = 16;
612 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
613 ok(result, "%08x\n", GetLastError());
615 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
617 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
618 ok(result, "%08x\n", GetLastError());
620 result = CryptDestroyKey(hKey);
621 ok(result, "%08x\n", GetLastError());
625 static void test_hmac(void) {
626 HCRYPTKEY hKey;
627 HCRYPTHASH hHash;
628 BOOL result;
629 /* Using CALG_MD2 here fails on Windows 2003, why ? */
630 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
631 DWORD dwLen;
632 BYTE abData[256];
633 static const BYTE hmac[16] = {
634 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
635 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
636 int i;
638 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
640 if (!derive_key(CALG_RC2, &hKey, 56)) return;
642 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
643 ok(result, "%08x\n", GetLastError());
644 if (!result) return;
646 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
647 ok(result, "%08x\n", GetLastError());
649 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
650 ok(result, "%08x\n", GetLastError());
652 dwLen = sizeof(abData)/sizeof(BYTE);
653 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
654 ok(result, "%08x\n", GetLastError());
656 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
658 result = CryptDestroyHash(hHash);
659 ok(result, "%08x\n", GetLastError());
661 result = CryptDestroyKey(hKey);
662 ok(result, "%08x\n", GetLastError());
664 /* Provoke errors */
665 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
666 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
669 static void test_mac(void) {
670 HCRYPTKEY hKey;
671 HCRYPTHASH hHash;
672 BOOL result;
673 DWORD dwLen;
674 BYTE abData[256], abEnc[264];
675 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
676 int i;
678 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
679 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
681 if (!derive_key(CALG_RC2, &hKey, 56)) return;
683 dwLen = 256;
684 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
685 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
687 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
688 ok(result, "%08x\n", GetLastError());
689 if (!result) return;
691 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
692 ok(result, "%08x\n", GetLastError());
694 dwLen = sizeof(abData)/sizeof(BYTE);
695 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
696 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
698 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
700 result = CryptDestroyHash(hHash);
701 ok(result, "%08x\n", GetLastError());
703 result = CryptDestroyKey(hKey);
704 ok(result, "%08x\n", GetLastError());
706 /* Provoke errors */
707 if (!derive_key(CALG_RC4, &hKey, 56)) return;
709 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
710 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
712 result = CryptDestroyKey(hKey);
713 ok(result, "%08x\n", GetLastError());
716 static BYTE abPlainPrivateKey[596] = {
717 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
718 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
719 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
720 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
721 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
722 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
723 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
724 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
725 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
726 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
727 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
728 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
729 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
730 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
731 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
732 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
733 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
734 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
735 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
736 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
737 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
738 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
739 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
740 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
741 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
742 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
743 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
744 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
745 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
746 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
747 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
748 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
749 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
750 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
751 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
752 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
753 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
754 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
755 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
756 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
757 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
758 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
759 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
760 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
761 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
762 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
763 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
764 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
765 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
766 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
767 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
768 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
769 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
770 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
771 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
772 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
773 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
774 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
775 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
776 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
777 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
778 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
779 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
780 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
781 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
782 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
783 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
784 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
785 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
786 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
787 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
788 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
789 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
790 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
791 0xf2, 0x5d, 0x58, 0x07
794 static void test_import_private(void)
796 DWORD dwLen;
797 HCRYPTKEY hKeyExchangeKey, hSessionKey;
798 BOOL result;
799 static BYTE abSessionKey[148] = {
800 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
801 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
802 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
803 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
804 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
805 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
806 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
807 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
808 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
809 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
810 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
811 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
812 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
813 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
814 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
815 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
816 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
817 0x04, 0x8c, 0x49, 0x92
819 static BYTE abEncryptedMessage[12] = {
820 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
821 0x1c, 0xfd, 0xde, 0x71
824 dwLen = (DWORD)sizeof(abPlainPrivateKey);
825 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
826 if (!result) {
827 /* rsaenh compiled without OpenSSL */
828 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
829 return;
832 dwLen = (DWORD)sizeof(abSessionKey);
833 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
834 ok(result, "%08x\n", GetLastError());
835 if (!result) return;
837 dwLen = (DWORD)sizeof(abEncryptedMessage);
838 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
839 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
840 "%08x, len: %d\n", GetLastError(), dwLen);
842 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
844 dwLen = (DWORD)sizeof(abSessionKey);
845 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
846 ok(result, "%08x\n", GetLastError());
847 if (!result) return;
849 dwLen = (DWORD)sizeof(abSessionKey);
850 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
851 ok(result, "%08x\n", GetLastError());
852 if (!result) return;
855 static void test_verify_signature(void) {
856 HCRYPTHASH hHash;
857 HCRYPTKEY hPubSignKey;
858 BYTE abData[] = "Wine rocks!";
859 BOOL result;
860 BYTE abPubKey[148] = {
861 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
862 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
863 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
864 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
865 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
866 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
867 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
868 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
869 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
870 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
871 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
872 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
873 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
874 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
875 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
876 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
877 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
878 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
879 0xe1, 0x21, 0x50, 0xac
881 /* md2 with hash oid */
882 BYTE abSignatureMD2[128] = {
883 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
884 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
885 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
886 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
887 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
888 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
889 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
890 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
891 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
892 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
893 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
894 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
895 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
896 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
897 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
898 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
900 /* md2 without hash oid */
901 BYTE abSignatureMD2NoOID[128] = {
902 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
903 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
904 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
905 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
906 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
907 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
908 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
909 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
910 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
911 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
912 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
913 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
914 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
915 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
916 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
917 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
919 /* md4 with hash oid */
920 BYTE abSignatureMD4[128] = {
921 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
922 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
923 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
924 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
925 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
926 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
927 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
928 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
929 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
930 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
931 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
932 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
933 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
934 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
935 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
936 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
938 /* md4 without hash oid */
939 BYTE abSignatureMD4NoOID[128] = {
940 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
941 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
942 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
943 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
944 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
945 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
946 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
947 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
948 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
949 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
950 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
951 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
952 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
953 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
954 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
955 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
957 /* md5 with hash oid */
958 BYTE abSignatureMD5[128] = {
959 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
960 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
961 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
962 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
963 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
964 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
965 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
966 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
967 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
968 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
969 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
970 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
971 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
972 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
973 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
974 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
976 /* md5 without hash oid */
977 BYTE abSignatureMD5NoOID[128] = {
978 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
979 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
980 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
981 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
982 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
983 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
984 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
985 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
986 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
987 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
988 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
989 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
990 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
991 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
992 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
993 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
995 /* sha with hash oid */
996 BYTE abSignatureSHA[128] = {
997 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
998 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
999 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1000 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1001 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1002 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1003 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1004 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1005 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1006 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1007 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1008 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1009 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1010 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1011 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1012 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1014 /* sha without hash oid */
1015 BYTE abSignatureSHANoOID[128] = {
1016 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1017 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1018 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1019 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1020 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1021 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1022 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1023 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1024 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1025 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1026 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1027 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1028 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1029 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1030 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1031 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1034 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1035 ok(result, "%08x\n", GetLastError());
1036 if (!result) return;
1038 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1039 ok(result, "%08x\n", GetLastError());
1040 if (!result) return;
1042 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1043 ok(result, "%08x\n", GetLastError());
1044 if (!result) return;
1046 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1047 ok(result, "%08x\n", GetLastError());
1048 if (!result) return;
1050 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1051 ok(result, "%08x\n", GetLastError());
1052 if (!result) return;
1054 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1055 * the OID at all. */
1056 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1057 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1058 if (result) return;*/
1060 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1061 ok(result, "%08x\n", GetLastError());
1062 if (!result) return;
1064 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1065 ok(result, "%08x\n", GetLastError());
1066 if (!result) return;
1068 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1069 ok(result, "%08x\n", GetLastError());
1070 if (!result) return;
1072 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1073 ok(result, "%08x\n", GetLastError());
1074 if (!result) return;
1076 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1077 ok(result, "%08x\n", GetLastError());
1078 if (!result) return;
1080 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1081 ok(result, "%08x\n", GetLastError());
1082 if (!result) return;
1084 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1085 ok(result, "%08x\n", GetLastError());
1086 if (!result) return;
1088 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1089 ok(result, "%08x\n", GetLastError());
1090 if (!result) return;
1092 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1093 ok(result, "%08x\n", GetLastError());
1094 if (!result) return;
1096 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1097 ok(result, "%08x\n", GetLastError());
1098 if (!result) return;
1100 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1101 ok(result, "%08x\n", GetLastError());
1102 if (!result) return;
1104 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1105 ok(result, "%08x\n", GetLastError());
1106 if (!result) return;
1109 static void test_rsa_encrypt(void)
1111 HCRYPTKEY hRSAKey;
1112 BYTE abData[2048] = "Wine rocks!";
1113 BOOL result;
1114 DWORD dwLen;
1116 /* It is allowed to use the key exchange key for encryption/decryption */
1117 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1118 ok (result, "%08x\n", GetLastError());
1119 if (!result) return;
1121 dwLen = 12;
1122 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1123 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1124 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1125 dwLen = 12;
1126 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1127 ok (result, "%08x\n", GetLastError());
1128 if (!result) return;
1130 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1131 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1133 CryptDestroyKey(hRSAKey);
1135 /* It is not allowed to use the signature key for encryption/decryption */
1136 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1137 ok (result, "%08x\n", GetLastError());
1138 if (!result) return;
1140 dwLen = 12;
1141 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1142 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1144 CryptDestroyKey(hRSAKey);
1147 static void test_import_export(void)
1149 DWORD dwLen, dwDataLen;
1150 HCRYPTKEY hPublicKey;
1151 BOOL result;
1152 ALG_ID algID;
1153 BYTE emptyKey[2048];
1154 static BYTE abPlainPublicKey[84] = {
1155 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1156 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1157 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1158 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1159 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1160 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1161 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1162 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1163 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1164 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1165 0x11, 0x11, 0x11, 0x11
1168 dwLen=84;
1169 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1170 ok(result, "failed to import the public key\n");
1172 dwDataLen=sizeof(algID);
1173 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1174 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1175 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1177 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1178 ok(result, "failed to export the fresh imported public key\n");
1179 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1180 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1183 static void test_schannel_provider(void)
1185 HCRYPTPROV hProv;
1186 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1187 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1188 BOOL result;
1189 DWORD dwLen;
1190 SCHANNEL_ALG saSChannelAlg;
1191 CRYPT_DATA_BLOB data_blob;
1192 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1193 BYTE abPlainPrivateKey[596] = {
1194 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1195 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1196 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1197 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1198 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1199 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1200 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1201 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1202 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1203 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1204 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1205 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1206 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1207 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1208 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1209 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1210 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1211 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1212 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1213 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1214 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1215 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1216 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1217 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1218 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1219 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1220 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1221 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1222 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1223 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1224 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1225 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1226 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1227 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1228 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1229 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1230 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1231 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1232 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1233 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1234 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1235 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1236 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1237 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1238 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1239 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1240 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1241 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1242 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1243 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1244 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1245 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1246 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1247 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1248 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1249 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1250 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1251 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1252 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1253 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1254 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1255 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1256 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1257 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1258 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1259 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1260 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1261 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1262 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1263 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1264 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1265 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1266 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1267 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1268 0xf2, 0x5d, 0x58, 0x07
1270 BYTE abTLS1Master[140] = {
1271 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1272 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1273 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1274 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1275 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1276 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1277 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1278 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1279 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1280 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1281 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1282 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1283 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1284 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1285 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1286 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1287 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1288 0xd3, 0x1e, 0x82, 0xb3
1290 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1291 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1292 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1293 BYTE abClientFinished[16] = "client finished";
1294 BYTE abData[16] = "Wine rocks!";
1295 BYTE abMD5Hash[16];
1296 static const BYTE abEncryptedData[16] = {
1297 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1298 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1300 static const BYTE abPRF[16] = {
1301 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1302 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1304 static const BYTE abMD5[16] = {
1305 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1306 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1309 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1310 ok (result, "%08x\n", GetLastError());
1311 if (!result) return;
1313 /* To get deterministic results, we import the TLS1 master secret (which
1314 * is typically generated from a random generator). Therefore, we need
1315 * an RSA key. */
1316 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1317 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1318 ok (result, "%08x\n", GetLastError());
1319 if (!result) return;
1321 dwLen = (DWORD)sizeof(abTLS1Master);
1322 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1323 ok (result, "%08x\n", GetLastError());
1324 if (!result) return;
1326 /* Setting the TLS1 client and server random parameters, as well as the
1327 * MAC and encryption algorithm parameters. */
1328 data_blob.cbData = 33;
1329 data_blob.pbData = abClientSecret;
1330 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1331 ok (result, "%08x\n", GetLastError());
1332 if (!result) return;
1334 data_blob.cbData = 33;
1335 data_blob.pbData = abServerSecret;
1336 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1337 ok (result, "%08x\n", GetLastError());
1338 if (!result) return;
1340 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1341 saSChannelAlg.Algid = CALG_DES;
1342 saSChannelAlg.cBits = 64;
1343 saSChannelAlg.dwFlags = 0;
1344 saSChannelAlg.dwReserved = 0;
1345 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1346 ok (result, "%08x\n", GetLastError());
1347 if (!result) return;
1349 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1350 saSChannelAlg.Algid = CALG_MD5;
1351 saSChannelAlg.cBits = 128;
1352 saSChannelAlg.dwFlags = 0;
1353 saSChannelAlg.dwReserved = 0;
1354 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1355 ok (result, "%08x\n", GetLastError());
1356 if (!result) return;
1358 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1359 * (Keys can only be derived from hashes, not from other keys.) */
1360 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1361 ok (result, "%08x\n", GetLastError());
1362 if (!result) return;
1364 /* Deriving the server write encryption key from the master hash */
1365 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1366 ok (result, "%08x\n", GetLastError());
1367 if (!result) return;
1369 /* Encrypting some data with the server write encryption key and checking the result. */
1370 dwLen = 12;
1371 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1372 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1374 /* Second test case: Test the TLS1 pseudo random number function. */
1375 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1376 ok (result, "%08x\n", GetLastError());
1377 if (!result) return;
1379 /* Set the label and seed parameters for the random number function */
1380 data_blob.cbData = 36;
1381 data_blob.pbData = abHashedHandshakes;
1382 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1383 ok (result, "%08x\n", GetLastError());
1384 if (!result) return;
1386 data_blob.cbData = 15;
1387 data_blob.pbData = abClientFinished;
1388 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1389 ok (result, "%08x\n", GetLastError());
1390 if (!result) return;
1392 /* Generate some pseudo random bytes and check if they are correct. */
1393 dwLen = (DWORD)sizeof(abData);
1394 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1395 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1396 "%08x\n", GetLastError());
1398 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1399 * Hash some data with the HMAC. Compare results. */
1400 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1401 ok (result, "%08x\n", GetLastError());
1402 if (!result) return;
1404 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1405 ok (result, "%08x\n", GetLastError());
1406 if (!result) return;
1408 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1409 ok (result, "%08x\n", GetLastError());
1410 if (!result) return;
1412 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1413 ok (result, "%08x\n", GetLastError());
1414 if (!result) return;
1416 dwLen = (DWORD)sizeof(abMD5Hash);
1417 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1418 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1420 CryptDestroyHash(hHMAC);
1421 CryptDestroyHash(hTLS1PRF);
1422 CryptDestroyHash(hMasterHash);
1423 CryptDestroyKey(hServerWriteMACKey);
1424 CryptDestroyKey(hServerWriteKey);
1425 CryptDestroyKey(hRSAKey);
1426 CryptDestroyKey(hMasterSecret);
1427 CryptReleaseContext(hProv, 0);
1428 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1431 static void test_enum_container(void)
1433 BYTE abContainerName[256];
1434 DWORD dwBufferLen;
1435 BOOL result, fFound = FALSE;
1437 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1438 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1439 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1440 ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1442 /* If the result fits into abContainerName dwBufferLen is left untouched */
1443 dwBufferLen = (DWORD)sizeof(abContainerName);
1444 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1445 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1447 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1448 do {
1449 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1450 dwBufferLen = (DWORD)sizeof(abContainerName);
1451 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1453 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1456 static BYTE signBlob[] = {
1457 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1458 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1459 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1460 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1461 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1462 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1463 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1464 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1465 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1466 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1467 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1468 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1469 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1470 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1471 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1472 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1473 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1474 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1475 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1476 0xb6,0x85,0x86,0x07 };
1478 static void test_null_provider(void)
1480 HCRYPTPROV prov;
1481 HCRYPTKEY key;
1482 BOOL result;
1483 DWORD keySpec, dataLen;
1485 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1486 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1487 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1488 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1489 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1490 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1491 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1492 CRYPT_DELETEKEYSET);
1493 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1494 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1495 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1496 CRYPT_DELETEKEYSET);
1497 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1498 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1499 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1500 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1501 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1503 /* Delete the default container. */
1504 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1505 /* Once you've deleted the default container you can't open it as if it
1506 * already exists.
1508 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1509 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1510 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1511 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1512 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1513 CRYPT_VERIFYCONTEXT);
1514 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1515 if (!result) return;
1516 dataLen = sizeof(keySpec);
1517 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1518 if (result)
1519 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1520 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1521 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1522 * supported, you can't get the keys from this container.
1524 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1525 ok(!result && GetLastError() == NTE_NO_KEY,
1526 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1527 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1528 ok(!result && GetLastError() == NTE_NO_KEY,
1529 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1530 result = CryptReleaseContext(prov, 0);
1531 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1532 /* You can create a new default container. */
1533 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1534 CRYPT_NEWKEYSET);
1535 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1536 /* But you still can't get the keys (until one's been generated.) */
1537 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1538 ok(!result && GetLastError() == NTE_NO_KEY,
1539 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1540 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1541 ok(!result && GetLastError() == NTE_NO_KEY,
1542 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1543 CryptReleaseContext(prov, 0);
1544 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1546 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1547 CRYPT_DELETEKEYSET);
1548 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1549 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1550 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1551 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1552 CRYPT_VERIFYCONTEXT);
1553 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1554 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1555 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1556 CRYPT_NEWKEYSET);
1557 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1558 if (!result) return;
1559 dataLen = sizeof(keySpec);
1560 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1561 if (result)
1562 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1563 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1564 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1565 ok(!result && GetLastError() == NTE_NO_KEY,
1566 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1567 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1568 ok(!result && GetLastError() == NTE_NO_KEY,
1569 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1571 /* Importing a key exchange blob.. */
1572 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1573 0, 0, &key);
1574 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1575 CryptDestroyKey(key);
1576 /* allows access to the key exchange key.. */
1577 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1578 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1579 CryptDestroyKey(key);
1580 /* but not to the private key. */
1581 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1582 ok(!result && GetLastError() == NTE_NO_KEY,
1583 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1584 CryptReleaseContext(prov, 0);
1585 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1586 CRYPT_DELETEKEYSET);
1588 /* Whereas importing a sign blob.. */
1589 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1590 CRYPT_NEWKEYSET);
1591 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1592 if (!result) return;
1593 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1594 ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1595 /* doesn't allow access to the key exchange key.. */
1596 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1597 ok(!result && GetLastError() == NTE_NO_KEY,
1598 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1599 /* but does to the private key. */
1600 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1601 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1602 CryptDestroyKey(key);
1604 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1605 CRYPT_DELETEKEYSET);
1608 /* test for the bug in accessing the user key in a container
1610 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1611 CRYPT_NEWKEYSET);
1612 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1613 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1614 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1615 CryptDestroyKey(key);
1616 CryptReleaseContext(prov,0);
1617 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1618 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1619 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1620 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1621 CryptDestroyKey(key);
1623 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1624 CRYPT_DELETEKEYSET);
1626 /* test the machine key set */
1627 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1628 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1629 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1630 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1631 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1632 CryptReleaseContext(prov, 0);
1633 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1634 CRYPT_MACHINE_KEYSET);
1635 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1636 CryptReleaseContext(prov,0);
1637 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1638 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1639 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1640 GetLastError());
1641 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1642 CRYPT_MACHINE_KEYSET);
1643 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1644 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1648 START_TEST(rsaenh)
1650 if (!init_environment())
1651 return;
1652 test_prov();
1653 test_gen_random();
1654 test_hashes();
1655 test_rc4();
1656 test_rc2();
1657 test_des();
1658 test_3des112();
1659 test_3des();
1660 test_hmac();
1661 test_mac();
1662 test_block_cipher_modes();
1663 test_import_private();
1664 test_verify_signature();
1665 test_rsa_encrypt();
1666 test_import_export();
1667 test_enum_container();
1668 clean_up_environment();
1669 test_schannel_provider();
1670 test_null_provider();