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
23 #include "wine/test.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 typedef struct _ctdatatype {
35 unsigned char origstr[32];
36 unsigned char decstr[32];
42 static const cryptdata cTestData[4] = {
44 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
47 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
50 {'a','b','c','d','e','f','g','h',0},
53 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
57 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
60 printf("%s: ",heading);
62 printf("0x%02x,",pb[i]);
66 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
69 static void trace_hex(BYTE *pbData, DWORD dwLen) {
73 for (i = 0; i < dwLen-7; i+=8) {
74 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
75 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
76 pbData[i+6], pbData[i+7]);
79 for (j=0; i<dwLen; j++,i++) {
80 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
86 static int init_environment(void)
91 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
93 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
95 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
96 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
98 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
100 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
101 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
102 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
104 ok(result, "%08x\n", GetLastError());
105 if (!result) return 0;
106 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
107 ok(result, "%08x\n", GetLastError());
108 if (result) CryptDestroyKey(hKey);
109 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
110 ok(result, "%08x\n", GetLastError());
111 if (result) CryptDestroyKey(hKey);
116 static void clean_up_environment(void)
120 result = CryptReleaseContext(hProv, 1);
121 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
123 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
126 static void test_prov(void)
131 dwLen = (DWORD)sizeof(DWORD);
132 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
133 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
135 dwLen = (DWORD)sizeof(DWORD);
136 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
137 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
140 static void test_gen_random(void)
143 BYTE rnd1[16], rnd2[16];
145 memset(rnd1, 0, sizeof(rnd1));
146 memset(rnd2, 0, sizeof(rnd2));
148 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
149 if (!result && GetLastError() == NTE_FAIL) {
150 /* rsaenh compiled without OpenSSL */
154 ok(result, "%08x\n", GetLastError());
156 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
157 ok(result, "%08x\n", GetLastError());
159 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
162 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
166 unsigned char pbData[2000];
169 *phKey = (HCRYPTKEY)NULL;
170 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
171 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
173 /* rsaenh compiled without OpenSSL */
174 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
177 ok(result, "%08x\n", GetLastError());
178 if (!result) return FALSE;
179 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
180 ok(result, "%08x\n", GetLastError());
181 if (!result) return FALSE;
182 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
183 ok(result, "%08x\n", GetLastError());
184 if (!result) return FALSE;
186 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
187 ok(result, "%08x\n", GetLastError());
188 CryptDestroyHash(hHash);
192 static void test_hashes(void)
194 static const unsigned char md2hash[16] = {
195 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
196 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
197 static const unsigned char md4hash[16] = {
198 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
199 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
200 static const unsigned char empty_md5hash[16] = {
201 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
202 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
203 static const unsigned char md5hash[16] = {
204 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
205 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
206 static const unsigned char sha1hash[20] = {
207 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
208 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
209 unsigned char pbData[2048];
211 HCRYPTHASH hHash, hHashClone;
212 BYTE pbHashValue[36];
216 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
219 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
221 /* rsaenh compiled without OpenSSL */
222 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
224 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
225 ok(result, "%08x\n", GetLastError());
228 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
229 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
232 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
233 ok(result, "%08x\n", GetLastError());
235 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
237 result = CryptDestroyHash(hHash);
238 ok(result, "%08x\n", GetLastError());
242 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
243 ok(result, "%08x\n", GetLastError());
245 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
246 ok(result, "%08x\n", GetLastError());
249 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
250 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
253 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
254 ok(result, "%08x\n", GetLastError());
256 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
258 result = CryptDestroyHash(hHash);
259 ok(result, "%08x\n", GetLastError());
262 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
263 ok(result, "%08x\n", GetLastError());
266 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
267 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
269 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
270 ok(result, "%08x\n", GetLastError());
273 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
274 ok(result, "%08x\n", GetLastError());
276 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
278 result = CryptDestroyHash(hHash);
279 ok(result, "%08x\n", GetLastError());
281 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
282 ok(result, "%08x\n", GetLastError());
284 /* The hash is available even if CryptHashData hasn't been called */
286 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
287 ok(result, "%08x\n", GetLastError());
289 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
291 /* It's also stable: getting it twice results in the same value */
292 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
293 ok(result, "%08x\n", GetLastError());
295 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
297 /* Can't add data after the hash been retrieved */
298 SetLastError(0xdeadbeef);
299 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
300 ok(!result && GetLastError() == NTE_BAD_HASH_STATE, "%08x\n", GetLastError());
302 /* You can still retrieve the hash, its value just hasn't changed */
303 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
304 ok(result, "%08x\n", GetLastError());
306 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
308 result = CryptDestroyHash(hHash);
309 ok(result, "%08x\n", GetLastError());
312 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
313 ok(result, "%08x\n", GetLastError());
315 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
316 ok(result, "%08x\n", GetLastError());
318 if(pCryptDuplicateHash) {
319 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
320 ok(result, "%08x\n", GetLastError());
322 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
323 ok(result, "%08x\n", GetLastError());
326 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
327 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
330 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
331 ok(result, "%08x\n", GetLastError());
333 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
335 result = CryptDestroyHash(hHashClone);
336 ok(result, "%08x\n", GetLastError());
339 result = CryptDestroyHash(hHash);
340 ok(result, "%08x\n", GetLastError());
343 static void test_block_cipher_modes(void)
345 static const BYTE plain[23] = {
346 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
347 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
348 static const BYTE ecb[24] = {
349 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
350 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
351 static const BYTE cbc[24] = {
352 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
353 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
354 static const BYTE cfb[24] = {
355 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
356 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
362 result = derive_key(CALG_RC2, &hKey, 40);
365 memcpy(abData, plain, sizeof(abData));
367 dwMode = CRYPT_MODE_ECB;
368 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
369 ok(result, "%08x\n", GetLastError());
372 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
373 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
374 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
376 SetLastError(ERROR_SUCCESS);
378 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
379 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
380 "%08x, dwLen: %d\n", GetLastError(), dwLen);
382 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
383 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
384 "%08x, dwLen: %d\n", GetLastError(), dwLen);
386 dwMode = CRYPT_MODE_CBC;
387 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
388 ok(result, "%08x\n", GetLastError());
391 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
392 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
393 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
396 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
397 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
398 "%08x, dwLen: %d\n", GetLastError(), dwLen);
400 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
401 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
402 "%08x, dwLen: %d\n", GetLastError(), dwLen);
404 dwMode = CRYPT_MODE_CFB;
405 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
406 ok(result, "%08x\n", GetLastError());
409 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
410 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
413 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
414 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
415 "%08x, dwLen: %d\n", GetLastError(), dwLen);
418 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
419 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
422 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
423 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
424 "%08x, dwLen: %d\n", GetLastError(), dwLen);
426 dwMode = CRYPT_MODE_OFB;
427 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
428 ok(result, "%08x\n", GetLastError());
431 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
432 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
435 static void test_3des112(void)
440 unsigned char pbData[16];
443 result = derive_key(CALG_3DES_112, &hKey, 0);
445 /* rsaenh compiled without OpenSSL */
446 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
450 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
453 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
454 ok(result, "%08x\n", GetLastError());
456 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
457 ok(result, "%08x\n", GetLastError());
461 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
463 dwLen = cTestData[i].enclen;
464 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
465 ok(result, "%08x\n", GetLastError());
466 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
468 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
469 ok(result, "%08x\n", GetLastError());
470 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
471 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
472 if((dwLen != cTestData[i].enclen) ||
473 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
475 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
476 printBytes("got",pbData,dwLen);
479 result = CryptDestroyKey(hKey);
480 ok(result, "%08x\n", GetLastError());
483 static void test_des(void)
488 unsigned char pbData[16];
491 result = derive_key(CALG_DES, &hKey, 56);
493 /* rsaenh compiled without OpenSSL */
494 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
498 dwMode = CRYPT_MODE_ECB;
499 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
500 ok(result, "%08x\n", GetLastError());
502 dwLen = sizeof(DWORD);
503 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
504 ok(result, "%08x\n", GetLastError());
506 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
509 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
510 ok(result, "%08x\n", GetLastError());
512 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
513 ok(result, "%08x\n", GetLastError());
517 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
519 dwLen = cTestData[i].enclen;
520 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
521 ok(result, "%08x\n", GetLastError());
522 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
524 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
525 ok(result, "%08x\n", GetLastError());
526 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
527 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
528 if((dwLen != cTestData[i].enclen) ||
529 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
531 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
532 printBytes("got",pbData,dwLen);
536 result = CryptDestroyKey(hKey);
537 ok(result, "%08x\n", GetLastError());
540 static void test_3des(void)
545 unsigned char pbData[16];
546 static const BYTE des3[16] = {
547 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
548 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
551 result = derive_key(CALG_3DES, &hKey, 0);
554 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
557 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
558 ok(result, "%08x\n", GetLastError());
560 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
562 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
563 ok(result, "%08x\n", GetLastError());
567 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
569 dwLen = cTestData[i].enclen;
570 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
571 ok(result, "%08x\n", GetLastError());
572 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
574 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
575 ok(result, "%08x\n", GetLastError());
576 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
577 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
578 if((dwLen != cTestData[i].enclen) ||
579 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
581 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
582 printBytes("got",pbData,dwLen);
585 result = CryptDestroyKey(hKey);
586 ok(result, "%08x\n", GetLastError());
589 static void test_rc2(void)
591 static const BYTE rc2encrypted[16] = {
592 0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
593 0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
594 static const BYTE rc2_128_encrypted[] = {
595 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
600 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
602 unsigned char pbData[2000], pbHashValue[16];
605 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
608 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
610 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
612 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
613 ok(result, "%08x\n", GetLastError());
616 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
617 ok(result, "%08x\n", GetLastError());
619 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
620 ok(result, "%08x\n", GetLastError());
622 dwLen = sizeof(DWORD);
623 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
624 ok(result, "%08x\n", GetLastError());
626 dwMode = CRYPT_MODE_CBC;
627 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
628 ok(result, "%08x\n", GetLastError());
630 dwLen = sizeof(DWORD);
631 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
632 ok(result, "%08x\n", GetLastError());
634 dwLen = sizeof(DWORD);
635 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
636 ok(result, "%08x\n", GetLastError());
638 dwLen = sizeof(DWORD);
639 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
640 ok(result, "%08x\n", GetLastError());
642 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
643 ok(result, "%08x\n", GetLastError());
644 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
645 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
646 HeapFree(GetProcessHeap(), 0, pbTemp);
648 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
649 ok(result, "%08x\n", GetLastError());
650 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
651 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
652 HeapFree(GetProcessHeap(), 0, pbTemp);
654 dwLen = sizeof(DWORD);
655 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
657 result = CryptDestroyHash(hHash);
658 ok(result, "%08x\n", GetLastError());
661 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
662 ok(result, "%08x\n", GetLastError());
664 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
666 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
667 ok(result, "%08x\n", GetLastError());
668 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
669 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
670 HeapFree(GetProcessHeap(), 0, pbTemp);
672 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
673 ok(result, "%08x\n", GetLastError());
675 result = CryptDestroyKey(hKey);
676 ok(result, "%08x\n", GetLastError());
679 /* Again, but test setting the effective key len */
680 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
682 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
684 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
686 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
687 ok(result, "%08x\n", GetLastError());
690 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
691 ok(result, "%08x\n", GetLastError());
693 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
694 ok(result, "%08x\n", GetLastError());
696 SetLastError(0xdeadbeef);
697 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
698 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
700 SetLastError(0xdeadbeef);
701 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
702 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
704 SetLastError(0xdeadbeef);
705 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
707 dwLen = sizeof(dwKeyLen);
708 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
709 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
710 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
711 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
714 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
715 ok(result, "%d\n", GetLastError());
717 dwLen = sizeof(dwKeyLen);
718 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
719 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
720 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
721 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
723 result = CryptDestroyHash(hHash);
724 ok(result, "%08x\n", GetLastError());
727 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
728 ok(result, "%08x\n", GetLastError());
730 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
731 "RC2 encryption failed!\n");
733 /* Oddly enough this succeeds, though it should have no effect */
735 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
736 ok(result, "%d\n", GetLastError());
738 result = CryptDestroyKey(hKey);
739 ok(result, "%08x\n", GetLastError());
743 static void test_rc4(void)
745 static const BYTE rc4[16] = {
746 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
747 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
751 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
752 unsigned char pbData[2000], *pbTemp;
753 unsigned char pszBuffer[256];
756 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
759 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
761 /* rsaenh compiled without OpenSSL */
762 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
764 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
765 ok(result, "%08x\n", GetLastError());
768 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
769 ok(result, "%08x\n", GetLastError());
771 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
772 ok(result, "%08x\n", GetLastError());
774 dwLen = sizeof(DWORD);
775 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
776 ok(result, "%08x\n", GetLastError());
778 dwLen = sizeof(DWORD);
779 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
780 ok(result, "%08x\n", GetLastError());
782 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
783 ok(result, "%08x\n", GetLastError());
784 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
785 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
786 HeapFree(GetProcessHeap(), 0, pbTemp);
788 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
789 ok(result, "%08x\n", GetLastError());
790 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
791 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
792 HeapFree(GetProcessHeap(), 0, pbTemp);
794 dwLen = sizeof(DWORD);
795 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
797 result = CryptDestroyHash(hHash);
798 ok(result, "%08x\n", GetLastError());
801 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
802 ok(result, "%08x\n", GetLastError());
804 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
805 ok(result, "%08x\n", GetLastError());
807 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
809 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
810 ok(result, "%08x\n", GetLastError());
812 result = CryptDestroyKey(hKey);
813 ok(result, "%08x\n", GetLastError());
817 static void test_hmac(void) {
821 /* Using CALG_MD2 here fails on Windows 2003, why ? */
822 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
825 static const BYTE hmac[16] = {
826 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
827 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
830 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
832 if (!derive_key(CALG_RC2, &hKey, 56)) return;
834 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
835 ok(result, "%08x\n", GetLastError());
838 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
839 ok(result, "%08x\n", GetLastError());
841 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
842 ok(result, "%08x\n", GetLastError());
844 dwLen = sizeof(abData)/sizeof(BYTE);
845 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
846 ok(result, "%08x\n", GetLastError());
848 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
850 result = CryptDestroyHash(hHash);
851 ok(result, "%08x\n", GetLastError());
853 result = CryptDestroyKey(hKey);
854 ok(result, "%08x\n", GetLastError());
857 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
858 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
861 static void test_mac(void) {
866 BYTE abData[256], abEnc[264];
867 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
870 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
871 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
873 if (!derive_key(CALG_RC2, &hKey, 56)) return;
876 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
877 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
879 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
880 ok(result, "%08x\n", GetLastError());
883 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
884 ok(result, "%08x\n", GetLastError());
886 dwLen = sizeof(abData)/sizeof(BYTE);
887 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
888 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
890 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
892 result = CryptDestroyHash(hHash);
893 ok(result, "%08x\n", GetLastError());
895 result = CryptDestroyKey(hKey);
896 ok(result, "%08x\n", GetLastError());
899 if (!derive_key(CALG_RC4, &hKey, 56)) return;
901 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
902 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
904 result = CryptDestroyKey(hKey);
905 ok(result, "%08x\n", GetLastError());
908 static BYTE abPlainPrivateKey[596] = {
909 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
910 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
911 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
912 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
913 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
914 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
915 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
916 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
917 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
918 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
919 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
920 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
921 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
922 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
923 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
924 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
925 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
926 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
927 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
928 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
929 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
930 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
931 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
932 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
933 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
934 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
935 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
936 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
937 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
938 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
939 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
940 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
941 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
942 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
943 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
944 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
945 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
946 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
947 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
948 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
949 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
950 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
951 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
952 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
953 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
954 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
955 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
956 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
957 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
958 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
959 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
960 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
961 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
962 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
963 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
964 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
965 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
966 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
967 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
968 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
969 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
970 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
971 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
972 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
973 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
974 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
975 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
976 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
977 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
978 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
979 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
980 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
981 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
982 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
983 0xf2, 0x5d, 0x58, 0x07
986 static void test_import_private(void)
989 HCRYPTKEY hKeyExchangeKey, hSessionKey;
991 static BYTE abSessionKey[148] = {
992 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
993 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
994 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
995 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
996 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
997 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
998 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
999 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1000 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1001 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1002 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1003 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1004 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1005 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1006 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1007 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1008 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1009 0x04, 0x8c, 0x49, 0x92
1011 static BYTE abEncryptedMessage[12] = {
1012 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1013 0x1c, 0xfd, 0xde, 0x71
1016 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1017 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1019 /* rsaenh compiled without OpenSSL */
1020 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1024 dwLen = (DWORD)sizeof(abSessionKey);
1025 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1026 ok(result, "%08x\n", GetLastError());
1027 if (!result) return;
1029 dwLen = (DWORD)sizeof(abEncryptedMessage);
1030 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1031 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1032 "%08x, len: %d\n", GetLastError(), dwLen);
1034 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1036 dwLen = (DWORD)sizeof(abSessionKey);
1037 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1038 ok(result, "%08x\n", GetLastError());
1039 if (!result) return;
1041 dwLen = (DWORD)sizeof(abSessionKey);
1042 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1043 ok(result, "%08x\n", GetLastError());
1044 if (!result) return;
1047 static void test_verify_signature(void) {
1049 HCRYPTKEY hPubSignKey;
1050 BYTE abData[] = "Wine rocks!";
1052 BYTE abPubKey[148] = {
1053 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1054 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1055 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1056 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1057 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1058 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1059 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1060 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1061 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1062 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1063 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1064 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1065 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1066 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1067 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1068 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1069 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1070 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1071 0xe1, 0x21, 0x50, 0xac
1073 /* md2 with hash oid */
1074 BYTE abSignatureMD2[128] = {
1075 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1076 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1077 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1078 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1079 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1080 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1081 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1082 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1083 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1084 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1085 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1086 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1087 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1088 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1089 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1090 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1092 /* md2 without hash oid */
1093 BYTE abSignatureMD2NoOID[128] = {
1094 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1095 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1096 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1097 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1098 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1099 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1100 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1101 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1102 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1103 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1104 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1105 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1106 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1107 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1108 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1109 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1111 /* md4 with hash oid */
1112 BYTE abSignatureMD4[128] = {
1113 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1114 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1115 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1116 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1117 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1118 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1119 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1120 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1121 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1122 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1123 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1124 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1125 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1126 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1127 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1128 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1130 /* md4 without hash oid */
1131 BYTE abSignatureMD4NoOID[128] = {
1132 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1133 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1134 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1135 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1136 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1137 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1138 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1139 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1140 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1141 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1142 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1143 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1144 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1145 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1146 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1147 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1149 /* md5 with hash oid */
1150 BYTE abSignatureMD5[128] = {
1151 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1152 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1153 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1154 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1155 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1156 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1157 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1158 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1159 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1160 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1161 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1162 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1163 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1164 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1165 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1166 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1168 /* md5 without hash oid */
1169 BYTE abSignatureMD5NoOID[128] = {
1170 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1171 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1172 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1173 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1174 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1175 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1176 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1177 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1178 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1179 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1180 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1181 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1182 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1183 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1184 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1185 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1187 /* sha with hash oid */
1188 BYTE abSignatureSHA[128] = {
1189 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1190 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1191 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1192 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1193 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1194 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1195 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1196 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1197 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1198 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1199 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1200 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1201 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1202 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1203 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1204 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1206 /* sha without hash oid */
1207 BYTE abSignatureSHANoOID[128] = {
1208 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1209 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1210 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1211 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1212 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1213 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1214 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1215 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1216 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1217 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1218 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1219 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1220 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1221 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1222 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1223 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1226 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1227 ok(result, "%08x\n", GetLastError());
1228 if (!result) return;
1230 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1231 ok(result, "%08x\n", GetLastError());
1232 if (!result) return;
1234 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1235 ok(result, "%08x\n", GetLastError());
1236 if (!result) return;
1238 /*check that a NULL pointer signature is correctly handled*/
1239 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1240 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1241 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1244 /* check that we get a bad signature error when the signature is too short*/
1245 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1246 ok(!result && NTE_BAD_SIGNATURE == GetLastError(),
1247 "Expected NTE_BAD_SIGNATURE error, got %08x\n", GetLastError());
1250 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1251 ok(result, "%08x\n", GetLastError());
1252 if (!result) return;
1254 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1255 ok(result, "%08x\n", GetLastError());
1256 if (!result) return;
1258 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1259 * the OID at all. */
1260 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1261 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1262 if (result) return;*/
1264 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1265 ok(result, "%08x\n", GetLastError());
1266 if (!result) return;
1268 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1269 ok(result, "%08x\n", GetLastError());
1270 if (!result) return;
1272 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1273 ok(result, "%08x\n", GetLastError());
1274 if (!result) return;
1276 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1277 ok(result, "%08x\n", GetLastError());
1278 if (!result) return;
1280 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1281 ok(result, "%08x\n", GetLastError());
1282 if (!result) return;
1284 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1285 ok(result, "%08x\n", GetLastError());
1286 if (!result) return;
1288 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1289 ok(result, "%08x\n", GetLastError());
1290 if (!result) return;
1292 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1293 ok(result, "%08x\n", GetLastError());
1294 if (!result) return;
1296 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1297 ok(result, "%08x\n", GetLastError());
1298 if (!result) return;
1300 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1301 ok(result, "%08x\n", GetLastError());
1302 if (!result) return;
1304 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1305 ok(result, "%08x\n", GetLastError());
1306 if (!result) return;
1308 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1309 ok(result, "%08x\n", GetLastError());
1310 if (!result) return;
1313 static void test_rsa_encrypt(void)
1316 BYTE abData[2048] = "Wine rocks!";
1320 /* It is allowed to use the key exchange key for encryption/decryption */
1321 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1322 ok (result, "%08x\n", GetLastError());
1323 if (!result) return;
1326 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1327 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1328 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1330 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1331 ok (result, "%08x\n", GetLastError());
1332 if (!result) return;
1334 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1335 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1337 CryptDestroyKey(hRSAKey);
1339 /* It is not allowed to use the signature key for encryption/decryption */
1340 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1341 ok (result, "%08x\n", GetLastError());
1342 if (!result) return;
1345 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1346 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1348 CryptDestroyKey(hRSAKey);
1351 static void test_import_export(void)
1353 DWORD dwLen, dwDataLen;
1354 HCRYPTKEY hPublicKey;
1357 BYTE emptyKey[2048];
1358 static BYTE abPlainPublicKey[84] = {
1359 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1360 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1361 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1362 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1363 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1364 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1365 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1366 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1367 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1368 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1369 0x11, 0x11, 0x11, 0x11
1373 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1374 ok(result, "failed to import the public key\n");
1376 dwDataLen=sizeof(algID);
1377 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1378 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1379 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1381 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1382 ok(result, "failed to export the fresh imported public key\n");
1383 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1384 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1387 static void test_schannel_provider(void)
1390 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1391 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1394 SCHANNEL_ALG saSChannelAlg;
1395 CRYPT_DATA_BLOB data_blob;
1396 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1397 BYTE abPlainPrivateKey[596] = {
1398 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1399 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1400 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1401 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1402 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1403 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1404 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1405 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1406 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1407 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1408 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1409 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1410 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1411 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1412 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1413 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1414 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1415 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1416 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1417 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1418 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1419 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1420 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1421 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1422 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1423 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1424 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1425 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1426 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1427 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1428 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1429 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1430 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1431 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1432 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1433 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1434 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1435 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1436 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1437 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1438 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1439 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1440 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1441 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1442 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1443 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1444 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1445 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1446 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1447 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1448 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1449 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1450 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1451 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1452 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1453 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1454 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1455 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1456 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1457 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1458 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1459 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1460 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1461 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1462 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1463 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1464 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1465 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1466 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1467 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1468 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1469 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1470 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1471 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1472 0xf2, 0x5d, 0x58, 0x07
1474 BYTE abTLS1Master[140] = {
1475 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1476 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1477 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1478 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1479 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1480 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1481 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1482 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1483 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1484 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1485 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1486 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1487 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1488 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1489 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1490 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1491 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1492 0xd3, 0x1e, 0x82, 0xb3
1494 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1495 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1496 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1497 BYTE abClientFinished[16] = "client finished";
1498 BYTE abData[16] = "Wine rocks!";
1500 static const BYTE abEncryptedData[16] = {
1501 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1502 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1504 static const BYTE abPRF[16] = {
1505 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1506 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1508 static const BYTE abMD5[16] = {
1509 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1510 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1513 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1514 ok (result, "%08x\n", GetLastError());
1516 CryptReleaseContext(hProv, 0);
1518 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1519 ok (result, "%08x\n", GetLastError());
1520 if (!result) return;
1522 /* To get deterministic results, we import the TLS1 master secret (which
1523 * is typically generated from a random generator). Therefore, we need
1525 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1526 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1527 ok (result, "%08x\n", GetLastError());
1528 if (!result) return;
1530 dwLen = (DWORD)sizeof(abTLS1Master);
1531 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1532 ok (result, "%08x\n", GetLastError());
1533 if (!result) return;
1535 /* Setting the TLS1 client and server random parameters, as well as the
1536 * MAC and encryption algorithm parameters. */
1537 data_blob.cbData = 33;
1538 data_blob.pbData = abClientSecret;
1539 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1540 ok (result, "%08x\n", GetLastError());
1541 if (!result) return;
1543 data_blob.cbData = 33;
1544 data_blob.pbData = abServerSecret;
1545 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1546 ok (result, "%08x\n", GetLastError());
1547 if (!result) return;
1549 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1550 saSChannelAlg.Algid = CALG_DES;
1551 saSChannelAlg.cBits = 64;
1552 saSChannelAlg.dwFlags = 0;
1553 saSChannelAlg.dwReserved = 0;
1554 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1555 ok (result, "%08x\n", GetLastError());
1556 if (!result) return;
1558 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1559 saSChannelAlg.Algid = CALG_MD5;
1560 saSChannelAlg.cBits = 128;
1561 saSChannelAlg.dwFlags = 0;
1562 saSChannelAlg.dwReserved = 0;
1563 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1564 ok (result, "%08x\n", GetLastError());
1565 if (!result) return;
1567 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1568 * (Keys can only be derived from hashes, not from other keys.) */
1569 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1570 ok (result, "%08x\n", GetLastError());
1571 if (!result) return;
1573 /* Deriving the server write encryption key from the master hash */
1574 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1575 ok (result, "%08x\n", GetLastError());
1576 if (!result) return;
1578 /* Encrypting some data with the server write encryption key and checking the result. */
1580 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1581 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1583 /* Second test case: Test the TLS1 pseudo random number function. */
1584 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1585 ok (result, "%08x\n", GetLastError());
1586 if (!result) return;
1588 /* Set the label and seed parameters for the random number function */
1589 data_blob.cbData = 36;
1590 data_blob.pbData = abHashedHandshakes;
1591 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1592 ok (result, "%08x\n", GetLastError());
1593 if (!result) return;
1595 data_blob.cbData = 15;
1596 data_blob.pbData = abClientFinished;
1597 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1598 ok (result, "%08x\n", GetLastError());
1599 if (!result) return;
1601 /* Generate some pseudo random bytes and check if they are correct. */
1602 dwLen = (DWORD)sizeof(abData);
1603 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1604 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1605 "%08x\n", GetLastError());
1607 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1608 * Hash some data with the HMAC. Compare results. */
1609 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1610 ok (result, "%08x\n", GetLastError());
1611 if (!result) return;
1613 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1614 ok (result, "%08x\n", GetLastError());
1615 if (!result) return;
1617 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1618 ok (result, "%08x\n", GetLastError());
1619 if (!result) return;
1621 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1622 ok (result, "%08x\n", GetLastError());
1623 if (!result) return;
1625 dwLen = (DWORD)sizeof(abMD5Hash);
1626 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1627 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1629 CryptDestroyHash(hHMAC);
1630 CryptDestroyHash(hTLS1PRF);
1631 CryptDestroyHash(hMasterHash);
1632 CryptDestroyKey(hServerWriteMACKey);
1633 CryptDestroyKey(hServerWriteKey);
1634 CryptDestroyKey(hRSAKey);
1635 CryptDestroyKey(hMasterSecret);
1636 CryptReleaseContext(hProv, 0);
1637 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1640 static void test_enum_container(void)
1642 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
1644 BOOL result, fFound = FALSE;
1646 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1647 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1648 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1649 ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1651 /* If the result fits into abContainerName dwBufferLen is left untouched */
1652 dwBufferLen = (DWORD)sizeof(abContainerName);
1653 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1654 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1656 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1658 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1659 dwBufferLen = (DWORD)sizeof(abContainerName);
1660 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1662 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1665 static BYTE signBlob[] = {
1666 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1667 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1668 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1669 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1670 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1671 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1672 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1673 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1674 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1675 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1676 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1677 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1678 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1679 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1680 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1681 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1682 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1683 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1684 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1685 0xb6,0x85,0x86,0x07 };
1687 static void test_null_provider(void)
1692 DWORD keySpec, dataLen,dwParam;
1693 char szName[MAX_PATH];
1695 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1696 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1697 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1698 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1699 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1700 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1701 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1702 CRYPT_DELETEKEYSET);
1703 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1704 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1705 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1706 CRYPT_DELETEKEYSET);
1707 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1708 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1709 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1710 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1711 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1713 /* Delete the default container. */
1714 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1715 /* Once you've deleted the default container you can't open it as if it
1718 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1719 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1720 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1721 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1722 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1723 CRYPT_VERIFYCONTEXT);
1724 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1725 if (!result) return;
1726 dataLen = sizeof(keySpec);
1727 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1729 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1730 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1731 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1732 * supported, you can't get the keys from this container.
1734 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1735 ok(!result && GetLastError() == NTE_NO_KEY,
1736 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1737 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1738 ok(!result && GetLastError() == NTE_NO_KEY,
1739 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1740 result = CryptReleaseContext(prov, 0);
1741 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1742 /* You can create a new default container. */
1743 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1745 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1746 /* But you still can't get the keys (until one's been generated.) */
1747 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1748 ok(!result && GetLastError() == NTE_NO_KEY,
1749 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1750 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1751 ok(!result && GetLastError() == NTE_NO_KEY,
1752 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1753 CryptReleaseContext(prov, 0);
1754 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1756 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1757 CRYPT_DELETEKEYSET);
1758 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1759 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1760 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1761 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1762 CRYPT_VERIFYCONTEXT);
1763 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1764 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1765 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1767 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1768 if (!result) return;
1769 /* Test provider parameters getter */
1770 dataLen = sizeof(dwParam);
1771 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1772 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1773 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1774 dataLen = sizeof(dwParam);
1775 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1776 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1777 "Expected 0, got 0x%08X\n",dwParam);
1778 dataLen = sizeof(dwParam);
1779 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1780 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1781 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1782 dataLen = sizeof(keySpec);
1783 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1784 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1785 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1786 /* PP_CONTAINER parameter */
1787 dataLen = sizeof(szName);
1788 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1789 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1790 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1791 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1792 /* PP_UNIQUE_CONTAINER parameter */
1793 dataLen = sizeof(szName);
1794 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1795 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1796 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1797 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1798 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1799 ok(!result && GetLastError() == NTE_NO_KEY,
1800 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1801 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1802 ok(!result && GetLastError() == NTE_NO_KEY,
1803 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1805 /* Importing a key exchange blob.. */
1806 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1808 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1809 CryptDestroyKey(key);
1810 /* allows access to the key exchange key.. */
1811 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1812 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1813 CryptDestroyKey(key);
1814 /* but not to the private key. */
1815 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1816 ok(!result && GetLastError() == NTE_NO_KEY,
1817 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1818 CryptReleaseContext(prov, 0);
1819 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1820 CRYPT_DELETEKEYSET);
1822 /* Whereas importing a sign blob.. */
1823 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1825 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1826 if (!result) return;
1827 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1828 ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1829 /* doesn't allow access to the key exchange key.. */
1830 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1831 ok(!result && GetLastError() == NTE_NO_KEY,
1832 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1833 /* but does to the private key. */
1834 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1835 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1836 CryptDestroyKey(key);
1838 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1839 CRYPT_DELETEKEYSET);
1842 /* test for the bug in accessing the user key in a container
1844 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1846 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1847 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1848 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1849 CryptDestroyKey(key);
1850 CryptReleaseContext(prov,0);
1851 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1852 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1853 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1854 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1855 CryptDestroyKey(key);
1857 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1858 CRYPT_DELETEKEYSET);
1860 /* test the machine key set */
1861 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1862 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1863 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1864 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1865 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1866 CryptReleaseContext(prov, 0);
1867 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1868 CRYPT_MACHINE_KEYSET);
1869 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1870 CryptReleaseContext(prov,0);
1871 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1872 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1873 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1875 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1876 CRYPT_MACHINE_KEYSET);
1877 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1878 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1884 if (!init_environment())
1896 test_block_cipher_modes();
1897 test_import_private();
1898 test_verify_signature();
1900 test_import_export();
1901 test_enum_container();
1902 clean_up_environment();
1903 test_schannel_provider();
1904 test_null_provider();