2 * Unit tests for rsaenh functions
4 * Copyright (c) 2004 Michael Jung
5 * Copyright (c) 2006 Juan Lang
6 * Copyright (c) 2007 Vijay Kiran Kamuju
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
32 static HCRYPTPROV hProv;
33 static const char szContainer[] = "winetest";
34 static const char szProvider[] = MS_ENHANCED_PROV_A;
36 typedef struct _ctdatatype {
37 unsigned char origstr[32];
38 unsigned char decstr[32];
44 static const cryptdata cTestData[4] = {
46 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
49 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
52 {'a','b','c','d','e','f','g','h',0},
55 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
60 * 1. Take the MD5 Hash of the container name (with an extra null byte)
61 * 2. Turn the hash into a 4 DWORD hex value
63 * 4. Add the MachineGuid
66 static void uniquecontainer(char *unique)
68 /* MD5 hash of "winetest\0" in 4 DWORD hex */
69 static const char szContainer_md5[] = "9d20fd8d05ed2b8455d125d0bf6d6a70";
70 static const char szCryptography[] = "Software\\Microsoft\\Cryptography";
71 static const char szMachineGuid[] = "MachineGuid";
74 DWORD size = MAX_PATH;
76 /* Get the MachineGUID */
77 RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
78 RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
81 lstrcpy(unique, szContainer_md5);
83 lstrcat(unique, guid);
86 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
89 printf("%s: ",heading);
91 printf("0x%02x,",pb[i]);
95 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
98 static void trace_hex(BYTE *pbData, DWORD dwLen) {
102 for (i = 0; i < dwLen-7; i+=8) {
103 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
104 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
105 pbData[i+6], pbData[i+7]);
108 for (j=0; i<dwLen; j++,i++) {
109 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
115 static int init_base_environment(void)
120 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
122 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
124 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
125 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
127 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
129 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
130 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
131 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
133 ok(result, "%08x\n", GetLastError());
134 if (!result) return 0;
135 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
136 ok(result, "%08x\n", GetLastError());
137 if (result) CryptDestroyKey(hKey);
138 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
139 ok(result, "%08x\n", GetLastError());
140 if (result) CryptDestroyKey(hKey);
145 static void clean_up_base_environment(void)
149 SetLastError(0xdeadbeef);
150 result = CryptReleaseContext(hProv, 1);
151 ok(!result || broken(result) /* Win98 */, "Expected failure\n");
152 ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
154 /* Just to prove that Win98 also released the CSP */
155 SetLastError(0xdeadbeef);
156 result = CryptReleaseContext(hProv, 0);
157 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
159 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
162 static int init_aes_environment(void)
167 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
169 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
171 /* we are using NULL as provider name for RSA_AES provider as the provider
172 * names are different in Windows XP and Vista. Its different as to what
173 * its defined in the SDK on Windows XP.
174 * This provider is available on Windows XP, Windows 2003 and Vista. */
176 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
177 if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
179 win_skip("RSA_ASE provider not supported\n");
182 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
184 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
186 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
187 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
188 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
190 ok(result, "%08x\n", GetLastError());
191 if (!result) return 0;
192 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
193 ok(result, "%08x\n", GetLastError());
194 if (result) CryptDestroyKey(hKey);
195 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
196 ok(result, "%08x\n", GetLastError());
197 if (result) CryptDestroyKey(hKey);
202 static void clean_up_aes_environment(void)
206 result = CryptReleaseContext(hProv, 1);
207 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
209 CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
212 static void test_prov(void)
217 dwLen = (DWORD)sizeof(DWORD);
218 SetLastError(0xdeadbeef);
219 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
220 if (!result && GetLastError() == NTE_BAD_TYPE)
221 skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
223 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
225 dwLen = (DWORD)sizeof(DWORD);
226 SetLastError(0xdeadbeef);
227 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
228 if (!result && GetLastError() == NTE_BAD_TYPE)
229 skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
231 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
234 static void test_gen_random(void)
237 BYTE rnd1[16], rnd2[16];
239 memset(rnd1, 0, sizeof(rnd1));
240 memset(rnd2, 0, sizeof(rnd2));
242 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
243 if (!result && GetLastError() == NTE_FAIL) {
244 /* rsaenh compiled without OpenSSL */
248 ok(result, "%08x\n", GetLastError());
250 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
251 ok(result, "%08x\n", GetLastError());
253 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
256 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
260 unsigned char pbData[2000];
264 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
265 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
267 /* rsaenh compiled without OpenSSL */
268 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
271 ok(result, "%08x\n", GetLastError());
272 if (!result) return FALSE;
273 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
274 ok(result, "%08x\n", GetLastError());
275 if (!result) return FALSE;
276 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
277 ok(result, "%08x\n", GetLastError());
278 if (!result) return FALSE;
280 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
281 ok(result, "%08x\n", GetLastError());
282 CryptDestroyHash(hHash);
286 static void test_hashes(void)
288 static const unsigned char md2hash[16] = {
289 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
290 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
291 static const unsigned char md4hash[16] = {
292 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
293 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
294 static const unsigned char empty_md5hash[16] = {
295 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
296 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
297 static const unsigned char md5hash[16] = {
298 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
299 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
300 static const unsigned char sha1hash[20] = {
301 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
302 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
303 unsigned char pbData[2048];
305 HCRYPTHASH hHash, hHashClone;
306 BYTE pbHashValue[36];
310 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
313 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
315 /* rsaenh compiled without OpenSSL */
316 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
318 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
319 ok(result, "%08x\n", GetLastError());
322 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
323 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
326 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
327 ok(result, "%08x\n", GetLastError());
329 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
331 result = CryptDestroyHash(hHash);
332 ok(result, "%08x\n", GetLastError());
336 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
337 ok(result, "%08x\n", GetLastError());
339 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
340 ok(result, "%08x\n", GetLastError());
343 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
344 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
347 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
348 ok(result, "%08x\n", GetLastError());
350 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
352 result = CryptDestroyHash(hHash);
353 ok(result, "%08x\n", GetLastError());
356 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
357 ok(result, "%08x\n", GetLastError());
360 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
361 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
363 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
364 ok(result, "%08x\n", GetLastError());
367 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
368 ok(result, "%08x\n", GetLastError());
370 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
372 result = CryptDestroyHash(hHash);
373 ok(result, "%08x\n", GetLastError());
375 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
376 ok(result, "%08x\n", GetLastError());
378 /* The hash is available even if CryptHashData hasn't been called */
380 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
381 ok(result, "%08x\n", GetLastError());
383 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
385 /* It's also stable: getting it twice results in the same value */
386 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
387 ok(result, "%08x\n", GetLastError());
389 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
391 /* Can't add data after the hash been retrieved */
392 SetLastError(0xdeadbeef);
393 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
394 ok(!result, "Expected failure\n");
395 ok(GetLastError() == NTE_BAD_HASH_STATE ||
396 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
397 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
399 /* You can still retrieve the hash, its value just hasn't changed */
400 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
401 ok(result, "%08x\n", GetLastError());
403 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
405 result = CryptDestroyHash(hHash);
406 ok(result, "%08x\n", GetLastError());
409 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
410 ok(result, "%08x\n", GetLastError());
412 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
413 ok(result, "%08x\n", GetLastError());
415 if(pCryptDuplicateHash) {
416 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
417 ok(result, "%08x\n", GetLastError());
419 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
420 ok(result, "%08x\n", GetLastError());
423 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
424 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
427 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
428 ok(result, "%08x\n", GetLastError());
430 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
432 result = CryptDestroyHash(hHashClone);
433 ok(result, "%08x\n", GetLastError());
436 result = CryptDestroyHash(hHash);
437 ok(result, "%08x\n", GetLastError());
440 static void test_block_cipher_modes(void)
442 static const BYTE plain[23] = {
443 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
444 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
445 static const BYTE ecb[24] = {
446 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
447 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
448 static const BYTE cbc[24] = {
449 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
450 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
451 static const BYTE cfb[24] = {
452 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
453 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
459 result = derive_key(CALG_RC2, &hKey, 40);
462 memcpy(abData, plain, sizeof(abData));
464 dwMode = CRYPT_MODE_ECB;
465 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
466 ok(result, "%08x\n", GetLastError());
469 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
470 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
471 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
473 SetLastError(ERROR_SUCCESS);
475 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
476 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
477 "%08x, dwLen: %d\n", GetLastError(), dwLen);
479 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
480 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
481 "%08x, dwLen: %d\n", GetLastError(), dwLen);
483 dwMode = CRYPT_MODE_CBC;
484 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
485 ok(result, "%08x\n", GetLastError());
488 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
489 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
490 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
493 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
494 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
495 "%08x, dwLen: %d\n", GetLastError(), dwLen);
497 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
498 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
499 "%08x, dwLen: %d\n", GetLastError(), dwLen);
501 dwMode = CRYPT_MODE_CFB;
502 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
503 ok(result, "%08x\n", GetLastError());
506 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
507 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
510 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
511 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
512 "%08x, dwLen: %d\n", GetLastError(), dwLen);
515 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
516 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
519 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
520 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
521 "%08x, dwLen: %d\n", GetLastError(), dwLen);
523 dwMode = CRYPT_MODE_OFB;
524 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
525 ok(result, "%08x\n", GetLastError());
528 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
529 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
531 CryptDestroyKey(hKey);
534 static void test_3des112(void)
539 unsigned char pbData[16];
542 result = derive_key(CALG_3DES_112, &hKey, 0);
544 /* rsaenh compiled without OpenSSL */
545 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
549 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
552 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
553 ok(result, "%08x\n", GetLastError());
555 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
556 ok(result, "%08x\n", GetLastError());
560 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
562 dwLen = cTestData[i].enclen;
563 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
564 ok(result, "%08x\n", GetLastError());
565 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
567 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
568 ok(result, "%08x\n", GetLastError());
569 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
570 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
571 if((dwLen != cTestData[i].enclen) ||
572 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
574 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
575 printBytes("got",pbData,dwLen);
578 result = CryptDestroyKey(hKey);
579 ok(result, "%08x\n", GetLastError());
582 static void test_des(void)
587 unsigned char pbData[16];
590 result = derive_key(CALG_DES, &hKey, 56);
592 /* rsaenh compiled without OpenSSL */
593 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
597 dwMode = CRYPT_MODE_ECB;
598 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
599 ok(result, "%08x\n", GetLastError());
601 dwLen = sizeof(DWORD);
602 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
603 ok(result, "%08x\n", GetLastError());
605 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
608 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
609 ok(result, "%08x\n", GetLastError());
611 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
612 ok(result, "%08x\n", GetLastError());
616 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
618 dwLen = cTestData[i].enclen;
619 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
620 ok(result, "%08x\n", GetLastError());
621 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
623 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
624 ok(result, "%08x\n", GetLastError());
625 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
626 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
627 if((dwLen != cTestData[i].enclen) ||
628 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
630 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
631 printBytes("got",pbData,dwLen);
635 result = CryptDestroyKey(hKey);
636 ok(result, "%08x\n", GetLastError());
639 static void test_3des(void)
644 unsigned char pbData[16];
645 static const BYTE des3[16] = {
646 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
647 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
650 result = derive_key(CALG_3DES, &hKey, 0);
653 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
656 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
657 ok(result, "%08x\n", GetLastError());
659 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
661 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
662 ok(result, "%08x\n", GetLastError());
666 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
668 dwLen = cTestData[i].enclen;
669 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
670 ok(result, "%08x\n", GetLastError());
671 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
673 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
674 ok(result, "%08x\n", GetLastError());
675 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
676 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
677 if((dwLen != cTestData[i].enclen) ||
678 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
680 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
681 printBytes("got",pbData,dwLen);
684 result = CryptDestroyKey(hKey);
685 ok(result, "%08x\n", GetLastError());
688 static void test_aes(int keylen)
693 unsigned char pbData[16];
699 result = derive_key(CALG_AES_256, &hKey, 0);
702 result = derive_key(CALG_AES_192, &hKey, 0);
706 result = derive_key(CALG_AES_128, &hKey, 0);
711 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
714 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
715 ok(result, "%08x\n", GetLastError());
717 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
718 ok(result, "%08x\n", GetLastError());
722 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
724 dwLen = cTestData[i].enclen;
725 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
726 ok(result, "%08x\n", GetLastError());
727 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
729 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
730 ok(result, "%08x\n", GetLastError());
731 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
732 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
733 if((dwLen != cTestData[i].enclen) ||
734 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
736 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
737 printBytes("got",pbData,dwLen);
740 result = CryptDestroyKey(hKey);
741 ok(result, "%08x\n", GetLastError());
744 static void test_rc2(void)
746 static const BYTE rc2_40_encrypted[16] = {
747 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
748 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
749 static const BYTE rc2_128_encrypted[] = {
750 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
755 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
757 unsigned char pbData[2000], pbHashValue[16];
760 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
763 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
765 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
767 CRYPT_INTEGER_BLOB salt;
769 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
770 ok(result, "%08x\n", GetLastError());
773 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
774 ok(result, "%08x\n", GetLastError());
776 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
777 ok(result, "%08x\n", GetLastError());
779 dwLen = sizeof(DWORD);
780 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
781 ok(result, "%08x\n", GetLastError());
783 dwMode = CRYPT_MODE_CBC;
784 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
785 ok(result, "%08x\n", GetLastError());
787 dwLen = sizeof(DWORD);
788 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
789 ok(result, "%08x\n", GetLastError());
791 dwLen = sizeof(DWORD);
792 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
793 ok(result, "%08x\n", GetLastError());
795 dwLen = sizeof(DWORD);
796 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
797 ok(result, "%08x\n", GetLastError());
799 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
800 ok(result, "%08x\n", GetLastError());
801 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
802 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
803 HeapFree(GetProcessHeap(), 0, pbTemp);
805 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
806 ok(result, "%08x\n", GetLastError());
807 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
808 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
809 HeapFree(GetProcessHeap(), 0, pbTemp);
811 dwLen = sizeof(DWORD);
812 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
814 result = CryptDestroyHash(hHash);
815 ok(result, "%08x\n", GetLastError());
818 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
819 ok(result, "%08x\n", GetLastError());
821 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
823 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
824 ok(result, "%08x\n", GetLastError());
825 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
826 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
827 HeapFree(GetProcessHeap(), 0, pbTemp);
829 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
830 ok(result, "%08x\n", GetLastError());
832 /* What sizes salt can I set? */
833 salt.pbData = pbData;
837 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
838 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
841 SetLastError(0xdeadbeef);
842 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
844 broken(result), /* Win9x, WinMe, NT4, W2K */
845 "%08x\n", GetLastError());
847 result = CryptDestroyKey(hKey);
848 ok(result, "%08x\n", GetLastError());
851 /* Again, but test setting the effective key len */
852 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
854 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
856 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
858 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
859 ok(result, "%08x\n", GetLastError());
862 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
863 ok(result, "%08x\n", GetLastError());
865 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
866 ok(result, "%08x\n", GetLastError());
868 SetLastError(0xdeadbeef);
869 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
870 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
872 SetLastError(0xdeadbeef);
873 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
874 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
876 SetLastError(0xdeadbeef);
877 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
879 dwLen = sizeof(dwKeyLen);
880 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
881 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
882 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
883 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
886 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
887 ok(result, "%d\n", GetLastError());
889 dwLen = sizeof(dwKeyLen);
890 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
891 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
892 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
893 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
895 result = CryptDestroyHash(hHash);
896 ok(result, "%08x\n", GetLastError());
899 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
900 ok(result, "%08x\n", GetLastError());
902 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
903 "RC2 encryption failed!\n");
905 /* Oddly enough this succeeds, though it should have no effect */
907 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
908 ok(result, "%d\n", GetLastError());
910 result = CryptDestroyKey(hKey);
911 ok(result, "%08x\n", GetLastError());
915 static void test_rc4(void)
917 static const BYTE rc4[16] = {
918 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
919 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
923 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
924 unsigned char pbData[2000], *pbTemp;
925 unsigned char pszBuffer[256];
928 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
931 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
933 /* rsaenh compiled without OpenSSL */
934 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
936 CRYPT_INTEGER_BLOB salt;
938 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
939 ok(result, "%08x\n", GetLastError());
942 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
943 ok(result, "%08x\n", GetLastError());
945 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
946 ok(result, "%08x\n", GetLastError());
948 dwLen = sizeof(DWORD);
949 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
950 ok(result, "%08x\n", GetLastError());
952 dwLen = sizeof(DWORD);
953 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
954 ok(result, "%08x\n", GetLastError());
956 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
957 ok(result, "%08x\n", GetLastError());
958 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
959 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
960 HeapFree(GetProcessHeap(), 0, pbTemp);
962 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
963 ok(result, "%08x\n", GetLastError());
964 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
965 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
966 HeapFree(GetProcessHeap(), 0, pbTemp);
968 dwLen = sizeof(DWORD);
969 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
971 result = CryptDestroyHash(hHash);
972 ok(result, "%08x\n", GetLastError());
975 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
976 ok(result, "%08x\n", GetLastError());
978 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
979 ok(result, "%08x\n", GetLastError());
981 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
983 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
984 ok(result, "%08x\n", GetLastError());
986 /* What sizes salt can I set? */
987 salt.pbData = pbData;
991 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
992 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
995 SetLastError(0xdeadbeef);
996 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
998 broken(result), /* Win9x, WinMe, NT4, W2K */
999 "%08x\n", GetLastError());
1001 result = CryptDestroyKey(hKey);
1002 ok(result, "%08x\n", GetLastError());
1006 static void test_hmac(void) {
1010 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1011 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1014 static const BYTE hmac[16] = {
1015 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1016 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1019 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1021 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1023 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1024 ok(result, "%08x\n", GetLastError());
1025 if (!result) return;
1027 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1028 ok(result, "%08x\n", GetLastError());
1030 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
1031 ok(result, "%08x\n", GetLastError());
1033 dwLen = sizeof(abData)/sizeof(BYTE);
1034 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1035 ok(result, "%08x\n", GetLastError());
1037 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1039 result = CryptDestroyHash(hHash);
1040 ok(result, "%08x\n", GetLastError());
1042 result = CryptDestroyKey(hKey);
1043 ok(result, "%08x\n", GetLastError());
1045 /* Provoke errors */
1046 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1047 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1050 static void test_mac(void) {
1055 BYTE abData[256], abEnc[264];
1056 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1059 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1060 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1062 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1065 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1066 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1068 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1069 ok(result, "%08x\n", GetLastError());
1070 if (!result) return;
1072 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
1073 ok(result, "%08x\n", GetLastError());
1075 dwLen = sizeof(abData)/sizeof(BYTE);
1076 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1077 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1079 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1081 result = CryptDestroyHash(hHash);
1082 ok(result, "%08x\n", GetLastError());
1084 result = CryptDestroyKey(hKey);
1085 ok(result, "%08x\n", GetLastError());
1087 /* Provoke errors */
1088 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1090 SetLastError(0xdeadbeef);
1091 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1092 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1093 broken(result), /* Win9x, WinMe, NT4, W2K */
1094 "%08x\n", GetLastError());
1096 result = CryptDestroyKey(hKey);
1097 ok(result, "%08x\n", GetLastError());
1100 static BYTE abPlainPrivateKey[596] = {
1101 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1102 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1103 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1104 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1105 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1106 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1107 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1108 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1109 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1110 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1111 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1112 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1113 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1114 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1115 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1116 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1117 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1118 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1119 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1120 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1121 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1122 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1123 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1124 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1125 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1126 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1127 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1128 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1129 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1130 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1131 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1132 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1133 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1134 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1135 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1136 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1137 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1138 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1139 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1140 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1141 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1142 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1143 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1144 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1145 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1146 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1147 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1148 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1149 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1150 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1151 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1152 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1153 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1154 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1155 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1156 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1157 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1158 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1159 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1160 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1161 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1162 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1163 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1164 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1165 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1166 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1167 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1168 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1169 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1170 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1171 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1172 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1173 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1174 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1175 0xf2, 0x5d, 0x58, 0x07
1178 static void test_import_private(void)
1181 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1183 static BYTE abSessionKey[148] = {
1184 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1185 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1186 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1187 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1188 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1189 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1190 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1191 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1192 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1193 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1194 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1195 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1196 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1197 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1198 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1199 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1200 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1201 0x04, 0x8c, 0x49, 0x92
1203 static BYTE abEncryptedMessage[12] = {
1204 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1205 0x1c, 0xfd, 0xde, 0x71
1208 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1209 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1211 /* rsaenh compiled without OpenSSL */
1212 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1216 dwLen = (DWORD)sizeof(abSessionKey);
1217 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1218 ok(result, "%08x\n", GetLastError());
1219 if (!result) return;
1221 dwLen = (DWORD)sizeof(abEncryptedMessage);
1222 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1223 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1224 "%08x, len: %d\n", GetLastError(), dwLen);
1225 CryptDestroyKey(hSessionKey);
1227 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1229 dwLen = (DWORD)sizeof(abSessionKey);
1230 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1231 ok(result, "%08x\n", GetLastError());
1232 CryptDestroyKey(hSessionKey);
1233 if (!result) return;
1235 dwLen = (DWORD)sizeof(abSessionKey);
1236 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1237 ok(result, "%08x\n", GetLastError());
1238 if (!result) return;
1240 CryptDestroyKey(hSessionKey);
1241 CryptDestroyKey(hKeyExchangeKey);
1244 static void test_verify_signature(void) {
1246 HCRYPTKEY hPubSignKey;
1247 BYTE abData[] = "Wine rocks!";
1249 BYTE abPubKey[148] = {
1250 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1251 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1252 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1253 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1254 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1255 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1256 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1257 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1258 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1259 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1260 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1261 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1262 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1263 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1264 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1265 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1266 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1267 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1268 0xe1, 0x21, 0x50, 0xac
1270 /* md2 with hash oid */
1271 BYTE abSignatureMD2[128] = {
1272 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1273 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1274 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1275 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1276 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1277 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1278 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1279 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1280 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1281 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1282 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1283 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1284 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1285 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1286 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1287 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1289 /* md2 without hash oid */
1290 BYTE abSignatureMD2NoOID[128] = {
1291 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1292 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1293 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1294 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1295 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1296 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1297 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1298 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1299 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1300 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1301 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1302 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1303 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1304 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1305 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1306 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1308 /* md4 with hash oid */
1309 BYTE abSignatureMD4[128] = {
1310 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1311 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1312 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1313 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1314 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1315 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1316 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1317 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1318 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1319 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1320 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1321 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1322 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1323 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1324 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1325 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1327 /* md4 without hash oid */
1328 BYTE abSignatureMD4NoOID[128] = {
1329 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1330 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1331 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1332 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1333 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1334 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1335 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1336 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1337 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1338 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1339 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1340 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1341 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1342 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1343 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1344 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1346 /* md5 with hash oid */
1347 BYTE abSignatureMD5[128] = {
1348 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1349 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1350 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1351 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1352 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1353 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1354 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1355 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1356 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1357 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1358 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1359 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1360 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1361 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1362 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1363 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1365 /* md5 without hash oid */
1366 BYTE abSignatureMD5NoOID[128] = {
1367 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1368 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1369 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1370 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1371 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1372 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1373 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1374 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1375 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1376 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1377 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1378 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1379 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1380 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1381 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1382 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1384 /* sha with hash oid */
1385 BYTE abSignatureSHA[128] = {
1386 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1387 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1388 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1389 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1390 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1391 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1392 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1393 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1394 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1395 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1396 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1397 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1398 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1399 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1400 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1401 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1403 /* sha without hash oid */
1404 BYTE abSignatureSHANoOID[128] = {
1405 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1406 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1407 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1408 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1409 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1410 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1411 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1412 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1413 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1414 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1415 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1416 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1417 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1418 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1419 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1420 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1423 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1424 ok(result, "%08x\n", GetLastError());
1425 if (!result) return;
1427 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1428 ok(result, "%08x\n", GetLastError());
1429 if (!result) return;
1431 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1432 ok(result, "%08x\n", GetLastError());
1433 if (!result) return;
1435 /*check that a NULL pointer signature is correctly handled*/
1436 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1437 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1438 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1441 /* check that we get a bad signature error when the signature is too short*/
1442 SetLastError(0xdeadbeef);
1443 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1444 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1445 broken(result), /* Win9x, WinMe, NT4 */
1446 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
1448 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1449 ok(result, "%08x\n", GetLastError());
1450 if (!result) return;
1452 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1453 ok(result, "%08x\n", GetLastError());
1454 if (!result) return;
1456 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1457 * the OID at all. */
1458 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1459 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1460 if (result) return;*/
1462 CryptDestroyHash(hHash);
1464 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1465 ok(result, "%08x\n", GetLastError());
1466 if (!result) return;
1468 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1469 ok(result, "%08x\n", GetLastError());
1470 if (!result) return;
1472 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1473 ok(result, "%08x\n", GetLastError());
1474 if (!result) return;
1476 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1477 ok(result, "%08x\n", GetLastError());
1478 if (!result) return;
1480 CryptDestroyHash(hHash);
1482 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1483 ok(result, "%08x\n", GetLastError());
1484 if (!result) return;
1486 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1487 ok(result, "%08x\n", GetLastError());
1488 if (!result) return;
1490 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1491 ok(result, "%08x\n", GetLastError());
1492 if (!result) return;
1494 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1495 ok(result, "%08x\n", GetLastError());
1496 if (!result) return;
1498 CryptDestroyHash(hHash);
1500 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1501 ok(result, "%08x\n", GetLastError());
1502 if (!result) return;
1504 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1505 ok(result, "%08x\n", GetLastError());
1506 if (!result) return;
1508 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1509 ok(result, "%08x\n", GetLastError());
1510 if (!result) return;
1512 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1513 ok(result, "%08x\n", GetLastError());
1514 if (!result) return;
1516 CryptDestroyHash(hHash);
1517 CryptDestroyKey(hPubSignKey);
1520 static void test_rsa_encrypt(void)
1523 BYTE abData[2048] = "Wine rocks!";
1527 /* It is allowed to use the key exchange key for encryption/decryption */
1528 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1529 ok (result, "%08x\n", GetLastError());
1530 if (!result) return;
1533 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1534 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1535 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1537 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1538 ok (result, "%08x\n", GetLastError());
1539 if (!result) return;
1541 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1542 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1544 CryptDestroyKey(hRSAKey);
1546 /* It is not allowed to use the signature key for encryption/decryption */
1547 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1548 ok (result, "%08x\n", GetLastError());
1549 if (!result) return;
1552 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1553 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1555 CryptDestroyKey(hRSAKey);
1558 static void test_import_export(void)
1560 DWORD dwLen, dwDataLen;
1561 HCRYPTKEY hPublicKey;
1564 BYTE emptyKey[2048];
1565 static BYTE abPlainPublicKey[84] = {
1566 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1567 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1568 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1569 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1570 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1571 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1572 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1573 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1574 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1575 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1576 0x11, 0x11, 0x11, 0x11
1580 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1581 ok(result, "failed to import the public key\n");
1583 dwDataLen=sizeof(algID);
1584 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1585 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1586 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1588 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1589 ok(result, "failed to export the fresh imported public key\n");
1590 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1591 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1593 CryptDestroyKey(hPublicKey);
1596 static void test_schannel_provider(void)
1599 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1600 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1603 SCHANNEL_ALG saSChannelAlg;
1604 CRYPT_DATA_BLOB data_blob;
1605 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1606 BYTE abTLS1Master[140] = {
1607 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1608 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1609 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1610 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1611 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1612 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1613 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1614 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1615 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1616 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1617 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1618 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1619 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1620 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1621 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1622 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1623 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1624 0xd3, 0x1e, 0x82, 0xb3
1626 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1627 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1628 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1629 BYTE abClientFinished[16] = "client finished";
1630 BYTE abData[16] = "Wine rocks!";
1632 static const BYTE abEncryptedData[16] = {
1633 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1634 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1636 static const BYTE abPRF[16] = {
1637 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1638 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1640 static const BYTE abMD5[16] = {
1641 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1642 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1645 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1648 win_skip("no PROV_RSA_SCHANNEL support\n");
1651 ok (result, "%08x\n", GetLastError());
1653 CryptReleaseContext(hProv, 0);
1655 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1656 ok (result, "%08x\n", GetLastError());
1657 if (!result) return;
1659 /* To get deterministic results, we import the TLS1 master secret (which
1660 * is typically generated from a random generator). Therefore, we need
1662 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1663 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1664 ok (result, "%08x\n", GetLastError());
1665 if (!result) return;
1667 dwLen = (DWORD)sizeof(abTLS1Master);
1668 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1669 ok (result, "%08x\n", GetLastError());
1670 if (!result) return;
1672 /* Setting the TLS1 client and server random parameters, as well as the
1673 * MAC and encryption algorithm parameters. */
1674 data_blob.cbData = 33;
1675 data_blob.pbData = abClientSecret;
1676 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1677 ok (result, "%08x\n", GetLastError());
1678 if (!result) return;
1680 data_blob.cbData = 33;
1681 data_blob.pbData = abServerSecret;
1682 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1683 ok (result, "%08x\n", GetLastError());
1684 if (!result) return;
1686 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1687 saSChannelAlg.Algid = CALG_DES;
1688 saSChannelAlg.cBits = 64;
1689 saSChannelAlg.dwFlags = 0;
1690 saSChannelAlg.dwReserved = 0;
1691 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1692 ok (result, "%08x\n", GetLastError());
1693 if (!result) return;
1695 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1696 saSChannelAlg.Algid = CALG_MD5;
1697 saSChannelAlg.cBits = 128;
1698 saSChannelAlg.dwFlags = 0;
1699 saSChannelAlg.dwReserved = 0;
1700 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1701 ok (result, "%08x\n", GetLastError());
1702 if (!result) return;
1704 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1705 * (Keys can only be derived from hashes, not from other keys.) */
1706 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1707 ok (result, "%08x\n", GetLastError());
1708 if (!result) return;
1710 /* Deriving the server write encryption key from the master hash */
1711 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1712 ok (result, "%08x\n", GetLastError());
1713 if (!result) return;
1715 /* Encrypting some data with the server write encryption key and checking the result. */
1717 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1718 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1720 /* Second test case: Test the TLS1 pseudo random number function. */
1721 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1722 ok (result, "%08x\n", GetLastError());
1723 if (!result) return;
1725 /* Set the label and seed parameters for the random number function */
1726 data_blob.cbData = 36;
1727 data_blob.pbData = abHashedHandshakes;
1728 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1729 ok (result, "%08x\n", GetLastError());
1730 if (!result) return;
1732 data_blob.cbData = 15;
1733 data_blob.pbData = abClientFinished;
1734 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1735 ok (result, "%08x\n", GetLastError());
1736 if (!result) return;
1738 /* Generate some pseudo random bytes and check if they are correct. */
1739 dwLen = (DWORD)sizeof(abData);
1740 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1741 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1742 "%08x\n", GetLastError());
1744 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1745 * Hash some data with the HMAC. Compare results. */
1746 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1747 ok (result, "%08x\n", GetLastError());
1748 if (!result) return;
1750 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1751 ok (result, "%08x\n", GetLastError());
1752 if (!result) return;
1754 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1755 ok (result, "%08x\n", GetLastError());
1756 if (!result) return;
1758 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1759 ok (result, "%08x\n", GetLastError());
1760 if (!result) return;
1762 dwLen = (DWORD)sizeof(abMD5Hash);
1763 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1764 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1766 CryptDestroyHash(hHMAC);
1767 CryptDestroyHash(hTLS1PRF);
1768 CryptDestroyHash(hMasterHash);
1769 CryptDestroyKey(hServerWriteMACKey);
1770 CryptDestroyKey(hServerWriteKey);
1771 CryptDestroyKey(hRSAKey);
1772 CryptDestroyKey(hMasterSecret);
1773 CryptReleaseContext(hProv, 0);
1774 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1777 static void test_enum_container(void)
1779 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
1781 BOOL result, fFound = FALSE;
1783 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1784 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1785 SetLastError(0xdeadbeef);
1786 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1787 ok (result, "%08x\n", GetLastError());
1788 ok (dwBufferLen == MAX_PATH + 1 ||
1789 broken(dwBufferLen == 10) || /* Win9x, WinMe */
1790 broken(dwBufferLen == 55), /* NT4 */
1791 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
1793 /* If the result fits into abContainerName dwBufferLen is left untouched */
1794 dwBufferLen = (DWORD)sizeof(abContainerName);
1795 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1796 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1798 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1800 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1801 dwBufferLen = (DWORD)sizeof(abContainerName);
1802 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1804 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1807 static BYTE signBlob[] = {
1808 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1809 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1810 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1811 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1812 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1813 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1814 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1815 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1816 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1817 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1818 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1819 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1820 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1821 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1822 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1823 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1824 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1825 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1826 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1827 0xb6,0x85,0x86,0x07 };
1829 static void test_null_provider(void)
1834 DWORD keySpec, dataLen,dwParam;
1835 char szName[MAX_PATH];
1837 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1838 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1839 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1840 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1841 ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
1842 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
1843 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1844 CRYPT_DELETEKEYSET);
1845 ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
1846 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
1847 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1848 CRYPT_DELETEKEYSET);
1849 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1850 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1851 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1852 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1853 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1855 /* Delete the default container. */
1856 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1857 /* Once you've deleted the default container you can't open it as if it
1860 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1861 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1862 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1863 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1864 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1865 CRYPT_VERIFYCONTEXT);
1866 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1867 if (!result) return;
1868 dataLen = sizeof(keySpec);
1869 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1871 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1872 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1873 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1874 * supported, you can't get the keys from this container.
1876 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1877 ok(!result && GetLastError() == NTE_NO_KEY,
1878 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1879 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1880 ok(!result && GetLastError() == NTE_NO_KEY,
1881 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1882 result = CryptReleaseContext(prov, 0);
1883 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1884 /* You can create a new default container. */
1885 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1887 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1888 /* But you still can't get the keys (until one's been generated.) */
1889 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1890 ok(!result && GetLastError() == NTE_NO_KEY,
1891 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1892 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1893 ok(!result && GetLastError() == NTE_NO_KEY,
1894 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1895 CryptReleaseContext(prov, 0);
1896 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1898 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1899 CRYPT_DELETEKEYSET);
1900 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1901 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1902 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1903 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1904 CRYPT_VERIFYCONTEXT);
1905 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1906 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1907 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1909 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1910 if (!result) return;
1911 /* Test provider parameters getter */
1912 dataLen = sizeof(dwParam);
1913 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1914 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1915 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1916 dataLen = sizeof(dwParam);
1917 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1918 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1919 "Expected 0, got 0x%08X\n",dwParam);
1920 dataLen = sizeof(dwParam);
1921 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1922 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1923 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1924 dataLen = sizeof(keySpec);
1925 SetLastError(0xdeadbeef);
1926 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1927 if (!result && GetLastError() == NTE_BAD_TYPE)
1928 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
1930 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1931 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1932 /* PP_CONTAINER parameter */
1933 dataLen = sizeof(szName);
1934 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1935 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1936 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1937 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1938 /* PP_UNIQUE_CONTAINER parameter */
1939 dataLen = sizeof(szName);
1940 SetLastError(0xdeadbeef);
1941 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1942 if (!result && GetLastError() == NTE_BAD_TYPE)
1944 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
1948 char container[MAX_PATH];
1950 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
1951 uniquecontainer(container);
1954 ok(dataLen == strlen(container)+1, "Expected a param length of 70, got %d\n", dataLen);
1955 ok(!strcmp(container, szName), "Wrong container name : %s\n", szName);
1958 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1959 ok(!result && GetLastError() == NTE_NO_KEY,
1960 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1961 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1962 ok(!result && GetLastError() == NTE_NO_KEY,
1963 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1965 /* Importing a key exchange blob.. */
1966 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1968 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1969 CryptDestroyKey(key);
1970 /* allows access to the key exchange key.. */
1971 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1972 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1973 CryptDestroyKey(key);
1974 /* but not to the private key. */
1975 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1976 ok(!result && GetLastError() == NTE_NO_KEY,
1977 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1978 CryptReleaseContext(prov, 0);
1979 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1980 CRYPT_DELETEKEYSET);
1982 /* Whereas importing a sign blob.. */
1983 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1985 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1986 if (!result) return;
1987 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1988 ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1989 CryptDestroyKey(key);
1990 /* doesn't allow access to the key exchange key.. */
1991 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1992 ok(!result && GetLastError() == NTE_NO_KEY,
1993 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1994 /* but does to the private key. */
1995 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1996 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1997 CryptDestroyKey(key);
1998 CryptReleaseContext(prov, 0);
2000 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2001 CRYPT_DELETEKEYSET);
2004 /* test for the bug in accessing the user key in a container
2006 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2008 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2009 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2010 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2011 CryptDestroyKey(key);
2012 CryptReleaseContext(prov,0);
2013 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2014 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2015 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2016 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2017 CryptDestroyKey(key);
2018 CryptReleaseContext(prov, 0);
2020 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2021 CRYPT_DELETEKEYSET);
2023 /* test the machine key set */
2024 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2025 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2026 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2027 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2028 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2029 CryptReleaseContext(prov, 0);
2030 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2031 CRYPT_MACHINE_KEYSET);
2032 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2033 CryptReleaseContext(prov,0);
2034 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2035 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2036 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2038 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2039 CRYPT_MACHINE_KEYSET);
2040 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2041 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2047 if (!init_base_environment())
2059 test_block_cipher_modes();
2060 test_import_private();
2061 test_verify_signature();
2063 test_import_export();
2064 test_enum_container();
2065 clean_up_base_environment();
2066 test_schannel_provider();
2067 test_null_provider();
2068 if (!init_aes_environment())
2073 clean_up_aes_environment();