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 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
37 static void trace_hex(BYTE *pbData, DWORD dwLen) {
41 for (i = 0; i < dwLen-7; i+=8) {
42 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
43 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
44 pbData[i+6], pbData[i+7]);
47 for (j=0; i<dwLen; j++,i++) {
48 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
54 static int init_environment(void)
59 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
61 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
63 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
64 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
66 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
68 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
69 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
70 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
72 ok(result, "%08x\n", GetLastError());
73 if (!result) return 0;
74 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
75 ok(result, "%08x\n", GetLastError());
76 if (result) CryptDestroyKey(hKey);
77 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
78 ok(result, "%08x\n", GetLastError());
79 if (result) CryptDestroyKey(hKey);
84 static void clean_up_environment(void)
88 result = CryptReleaseContext(hProv, 1);
89 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
91 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
94 static void test_prov(void)
99 dwLen = (DWORD)sizeof(DWORD);
100 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
101 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
103 dwLen = (DWORD)sizeof(DWORD);
104 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
105 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
108 static void test_gen_random(void)
111 BYTE rnd1[16], rnd2[16];
113 memset(rnd1, 0, sizeof(rnd1));
114 memset(rnd2, 0, sizeof(rnd2));
116 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
117 if (!result && GetLastError() == NTE_FAIL) {
118 /* rsaenh compiled without OpenSSL */
122 ok(result, "%08x\n", GetLastError());
124 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
125 ok(result, "%08x\n", GetLastError());
127 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
130 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
134 unsigned char pbData[2000];
137 *phKey = (HCRYPTKEY)NULL;
138 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
139 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
141 /* rsaenh compiled without OpenSSL */
142 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
145 ok(result, "%08x\n", GetLastError());
146 if (!result) return FALSE;
147 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
148 ok(result, "%08x\n", GetLastError());
149 if (!result) return FALSE;
150 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
151 ok(result, "%08x\n", GetLastError());
152 if (!result) return FALSE;
154 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
155 ok(result, "%08x\n", GetLastError());
156 CryptDestroyHash(hHash);
160 static void test_hashes(void)
162 static const unsigned char md2hash[16] = {
163 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
164 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
165 static const unsigned char md4hash[16] = {
166 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
167 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
168 static const unsigned char empty_md5hash[16] = {
169 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
170 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
171 static const unsigned char md5hash[16] = {
172 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
173 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
174 static const unsigned char sha1hash[20] = {
175 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
176 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
177 unsigned char pbData[2048];
179 HCRYPTHASH hHash, hHashClone;
180 BYTE pbHashValue[36];
184 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
187 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
189 /* rsaenh compiled without OpenSSL */
190 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
192 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
193 ok(result, "%08x\n", GetLastError());
196 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
197 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
200 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
201 ok(result, "%08x\n", GetLastError());
203 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
205 result = CryptDestroyHash(hHash);
206 ok(result, "%08x\n", GetLastError());
210 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
211 ok(result, "%08x\n", GetLastError());
213 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
214 ok(result, "%08x\n", GetLastError());
217 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
218 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
221 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
222 ok(result, "%08x\n", GetLastError());
224 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
226 result = CryptDestroyHash(hHash);
227 ok(result, "%08x\n", GetLastError());
230 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
231 ok(result, "%08x\n", GetLastError());
234 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
235 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
237 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
238 ok(result, "%08x\n", GetLastError());
241 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
242 ok(result, "%08x\n", GetLastError());
244 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
246 result = CryptDestroyHash(hHash);
247 ok(result, "%08x\n", GetLastError());
249 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
250 ok(result, "%08x\n", GetLastError());
252 /* The hash is available even if CryptHashData hasn't been called */
254 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
255 ok(result, "%08x\n", GetLastError());
257 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
259 /* It's also stable: getting it twice results in the same value */
260 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
261 ok(result, "%08x\n", GetLastError());
263 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
265 /* Can't add data after the hash been retrieved */
266 SetLastError(0xdeadbeef);
267 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
268 ok(!result && GetLastError() == NTE_BAD_HASH_STATE, "%08x\n", GetLastError());
270 /* You can still retrieve the hash, its value just hasn't changed */
271 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
272 ok(result, "%08x\n", GetLastError());
274 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
276 result = CryptDestroyHash(hHash);
277 ok(result, "%08x\n", GetLastError());
280 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
281 ok(result, "%08x\n", GetLastError());
283 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
284 ok(result, "%08x\n", GetLastError());
286 if(pCryptDuplicateHash) {
287 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
288 ok(result, "%08x\n", GetLastError());
290 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
291 ok(result, "%08x\n", GetLastError());
294 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
295 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
298 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
299 ok(result, "%08x\n", GetLastError());
301 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
303 result = CryptDestroyHash(hHashClone);
304 ok(result, "%08x\n", GetLastError());
307 result = CryptDestroyHash(hHash);
308 ok(result, "%08x\n", GetLastError());
311 static void test_block_cipher_modes(void)
313 static const BYTE plain[23] = {
314 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
315 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
316 static const BYTE ecb[24] = {
317 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
318 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
319 static const BYTE cbc[24] = {
320 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
321 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
322 static const BYTE cfb[24] = {
323 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
324 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
330 result = derive_key(CALG_RC2, &hKey, 40);
333 memcpy(abData, plain, sizeof(abData));
335 dwMode = CRYPT_MODE_ECB;
336 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
337 ok(result, "%08x\n", GetLastError());
340 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
341 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
342 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
344 SetLastError(ERROR_SUCCESS);
346 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
347 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
348 "%08x, dwLen: %d\n", GetLastError(), dwLen);
350 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
351 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
352 "%08x, dwLen: %d\n", GetLastError(), dwLen);
354 dwMode = CRYPT_MODE_CBC;
355 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
356 ok(result, "%08x\n", GetLastError());
359 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
360 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
361 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
364 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
365 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
366 "%08x, dwLen: %d\n", GetLastError(), dwLen);
368 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
369 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
370 "%08x, dwLen: %d\n", GetLastError(), dwLen);
372 dwMode = CRYPT_MODE_CFB;
373 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
374 ok(result, "%08x\n", GetLastError());
377 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
378 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
381 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
382 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
383 "%08x, dwLen: %d\n", GetLastError(), dwLen);
386 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
387 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
390 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
391 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
392 "%08x, dwLen: %d\n", GetLastError(), dwLen);
394 dwMode = CRYPT_MODE_OFB;
395 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
396 ok(result, "%08x\n", GetLastError());
399 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
400 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
403 static void test_3des112(void)
408 unsigned char pbData[16];
411 result = derive_key(CALG_3DES_112, &hKey, 0);
413 /* rsaenh compiled without OpenSSL */
414 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
418 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
421 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
422 ok(result, "%08x\n", GetLastError());
424 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
425 ok(result, "%08x\n", GetLastError());
427 result = CryptDestroyKey(hKey);
428 ok(result, "%08x\n", GetLastError());
431 static void test_des(void)
436 unsigned char pbData[16];
439 result = derive_key(CALG_DES, &hKey, 56);
441 /* rsaenh compiled without OpenSSL */
442 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
446 dwMode = CRYPT_MODE_ECB;
447 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
448 ok(result, "%08x\n", GetLastError());
450 dwLen = sizeof(DWORD);
451 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
452 ok(result, "%08x\n", GetLastError());
454 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
457 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
458 ok(result, "%08x\n", GetLastError());
460 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
461 ok(result, "%08x\n", GetLastError());
463 result = CryptDestroyKey(hKey);
464 ok(result, "%08x\n", GetLastError());
467 static void test_3des(void)
472 unsigned char pbData[16];
473 static const BYTE des3[16] = {
474 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
475 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
478 result = derive_key(CALG_3DES, &hKey, 0);
481 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
484 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
485 ok(result, "%08x\n", GetLastError());
487 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
489 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
490 ok(result, "%08x\n", GetLastError());
492 result = CryptDestroyKey(hKey);
493 ok(result, "%08x\n", GetLastError());
496 static void test_rc2(void)
498 static const BYTE rc2encrypted[16] = {
499 0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
500 0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
504 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
506 unsigned char pbData[2000], pbHashValue[16];
509 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
512 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
514 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
516 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
517 ok(result, "%08x\n", GetLastError());
520 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
521 ok(result, "%08x\n", GetLastError());
523 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
524 ok(result, "%08x\n", GetLastError());
526 dwLen = sizeof(DWORD);
527 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
528 ok(result, "%08x\n", GetLastError());
530 dwMode = CRYPT_MODE_CBC;
531 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
532 ok(result, "%08x\n", GetLastError());
534 dwLen = sizeof(DWORD);
535 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
536 ok(result, "%08x\n", GetLastError());
538 dwLen = sizeof(DWORD);
539 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
540 ok(result, "%08x\n", GetLastError());
542 dwLen = sizeof(DWORD);
543 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
544 ok(result, "%08x\n", GetLastError());
546 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
547 ok(result, "%08x\n", GetLastError());
548 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
549 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
550 HeapFree(GetProcessHeap(), 0, pbTemp);
552 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
553 ok(result, "%08x\n", GetLastError());
554 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
555 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
556 HeapFree(GetProcessHeap(), 0, pbTemp);
558 dwLen = sizeof(DWORD);
559 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
561 result = CryptDestroyHash(hHash);
562 ok(result, "%08x\n", GetLastError());
565 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
566 ok(result, "%08x\n", GetLastError());
568 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
570 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
571 ok(result, "%08x\n", GetLastError());
572 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
573 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
574 HeapFree(GetProcessHeap(), 0, pbTemp);
576 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
577 ok(result, "%08x\n", GetLastError());
579 result = CryptDestroyKey(hKey);
580 ok(result, "%08x\n", GetLastError());
584 static void test_rc4(void)
586 static const BYTE rc4[16] = {
587 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
588 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
592 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
593 unsigned char pbData[2000], *pbTemp;
594 unsigned char pszBuffer[256];
597 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
600 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
602 /* rsaenh compiled without OpenSSL */
603 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
605 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
606 ok(result, "%08x\n", GetLastError());
609 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
610 ok(result, "%08x\n", GetLastError());
612 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
613 ok(result, "%08x\n", GetLastError());
615 dwLen = sizeof(DWORD);
616 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
617 ok(result, "%08x\n", GetLastError());
619 dwLen = sizeof(DWORD);
620 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
621 ok(result, "%08x\n", GetLastError());
623 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
624 ok(result, "%08x\n", GetLastError());
625 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
626 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
627 HeapFree(GetProcessHeap(), 0, pbTemp);
629 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
630 ok(result, "%08x\n", GetLastError());
631 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
632 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
633 HeapFree(GetProcessHeap(), 0, pbTemp);
635 dwLen = sizeof(DWORD);
636 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
638 result = CryptDestroyHash(hHash);
639 ok(result, "%08x\n", GetLastError());
642 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
643 ok(result, "%08x\n", GetLastError());
645 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
646 ok(result, "%08x\n", GetLastError());
648 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
650 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
651 ok(result, "%08x\n", GetLastError());
653 result = CryptDestroyKey(hKey);
654 ok(result, "%08x\n", GetLastError());
658 static void test_hmac(void) {
662 /* Using CALG_MD2 here fails on Windows 2003, why ? */
663 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
666 static const BYTE hmac[16] = {
667 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
668 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
671 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
673 if (!derive_key(CALG_RC2, &hKey, 56)) return;
675 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
676 ok(result, "%08x\n", GetLastError());
679 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
680 ok(result, "%08x\n", GetLastError());
682 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
683 ok(result, "%08x\n", GetLastError());
685 dwLen = sizeof(abData)/sizeof(BYTE);
686 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
687 ok(result, "%08x\n", GetLastError());
689 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
691 result = CryptDestroyHash(hHash);
692 ok(result, "%08x\n", GetLastError());
694 result = CryptDestroyKey(hKey);
695 ok(result, "%08x\n", GetLastError());
698 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
699 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
702 static void test_mac(void) {
707 BYTE abData[256], abEnc[264];
708 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
711 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
712 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
714 if (!derive_key(CALG_RC2, &hKey, 56)) return;
717 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
718 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
720 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
721 ok(result, "%08x\n", GetLastError());
724 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
725 ok(result, "%08x\n", GetLastError());
727 dwLen = sizeof(abData)/sizeof(BYTE);
728 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
729 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
731 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
733 result = CryptDestroyHash(hHash);
734 ok(result, "%08x\n", GetLastError());
736 result = CryptDestroyKey(hKey);
737 ok(result, "%08x\n", GetLastError());
740 if (!derive_key(CALG_RC4, &hKey, 56)) return;
742 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
743 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
745 result = CryptDestroyKey(hKey);
746 ok(result, "%08x\n", GetLastError());
749 static BYTE abPlainPrivateKey[596] = {
750 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
751 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
752 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
753 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
754 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
755 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
756 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
757 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
758 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
759 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
760 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
761 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
762 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
763 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
764 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
765 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
766 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
767 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
768 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
769 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
770 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
771 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
772 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
773 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
774 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
775 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
776 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
777 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
778 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
779 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
780 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
781 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
782 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
783 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
784 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
785 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
786 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
787 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
788 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
789 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
790 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
791 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
792 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
793 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
794 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
795 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
796 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
797 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
798 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
799 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
800 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
801 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
802 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
803 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
804 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
805 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
806 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
807 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
808 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
809 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
810 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
811 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
812 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
813 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
814 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
815 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
816 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
817 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
818 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
819 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
820 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
821 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
822 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
823 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
824 0xf2, 0x5d, 0x58, 0x07
827 static void test_import_private(void)
830 HCRYPTKEY hKeyExchangeKey, hSessionKey;
832 static BYTE abSessionKey[148] = {
833 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
834 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
835 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
836 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
837 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
838 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
839 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
840 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
841 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
842 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
843 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
844 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
845 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
846 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
847 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
848 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
849 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
850 0x04, 0x8c, 0x49, 0x92
852 static BYTE abEncryptedMessage[12] = {
853 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
854 0x1c, 0xfd, 0xde, 0x71
857 dwLen = (DWORD)sizeof(abPlainPrivateKey);
858 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
860 /* rsaenh compiled without OpenSSL */
861 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
865 dwLen = (DWORD)sizeof(abSessionKey);
866 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
867 ok(result, "%08x\n", GetLastError());
870 dwLen = (DWORD)sizeof(abEncryptedMessage);
871 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
872 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
873 "%08x, len: %d\n", GetLastError(), dwLen);
875 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
877 dwLen = (DWORD)sizeof(abSessionKey);
878 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
879 ok(result, "%08x\n", GetLastError());
882 dwLen = (DWORD)sizeof(abSessionKey);
883 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
884 ok(result, "%08x\n", GetLastError());
888 static void test_verify_signature(void) {
890 HCRYPTKEY hPubSignKey;
891 BYTE abData[] = "Wine rocks!";
893 BYTE abPubKey[148] = {
894 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
895 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
896 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
897 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
898 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
899 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
900 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
901 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
902 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
903 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
904 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
905 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
906 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
907 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
908 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
909 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
910 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
911 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
912 0xe1, 0x21, 0x50, 0xac
914 /* md2 with hash oid */
915 BYTE abSignatureMD2[128] = {
916 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
917 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
918 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
919 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
920 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
921 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
922 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
923 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
924 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
925 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
926 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
927 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
928 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
929 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
930 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
931 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
933 /* md2 without hash oid */
934 BYTE abSignatureMD2NoOID[128] = {
935 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
936 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
937 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
938 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
939 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
940 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
941 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
942 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
943 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
944 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
945 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
946 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
947 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
948 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
949 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
950 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
952 /* md4 with hash oid */
953 BYTE abSignatureMD4[128] = {
954 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
955 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
956 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
957 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
958 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
959 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
960 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
961 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
962 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
963 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
964 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
965 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
966 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
967 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
968 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
969 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
971 /* md4 without hash oid */
972 BYTE abSignatureMD4NoOID[128] = {
973 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
974 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
975 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
976 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
977 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
978 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
979 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
980 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
981 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
982 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
983 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
984 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
985 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
986 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
987 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
988 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
990 /* md5 with hash oid */
991 BYTE abSignatureMD5[128] = {
992 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
993 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
994 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
995 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
996 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
997 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
998 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
999 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1000 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1001 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1002 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1003 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1004 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1005 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1006 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1007 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1009 /* md5 without hash oid */
1010 BYTE abSignatureMD5NoOID[128] = {
1011 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1012 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1013 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1014 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1015 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1016 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1017 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1018 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1019 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1020 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1021 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1022 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1023 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1024 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1025 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1026 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1028 /* sha with hash oid */
1029 BYTE abSignatureSHA[128] = {
1030 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1031 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1032 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1033 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1034 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1035 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1036 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1037 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1038 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1039 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1040 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1041 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1042 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1043 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1044 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1045 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1047 /* sha without hash oid */
1048 BYTE abSignatureSHANoOID[128] = {
1049 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1050 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1051 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1052 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1053 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1054 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1055 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1056 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1057 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1058 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1059 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1060 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1061 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1062 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1063 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1064 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1067 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1068 ok(result, "%08x\n", GetLastError());
1069 if (!result) return;
1071 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1072 ok(result, "%08x\n", GetLastError());
1073 if (!result) return;
1075 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1076 ok(result, "%08x\n", GetLastError());
1077 if (!result) return;
1079 /*check that a NULL pointer signature is correctly handled*/
1080 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1081 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1082 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1085 /* check that we get a bad signature error when the signature is too short*/
1086 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1087 ok(!result && NTE_BAD_SIGNATURE == GetLastError(),
1088 "Expected NTE_BAD_SIGNATURE error, got %08x\n", GetLastError());
1091 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1092 ok(result, "%08x\n", GetLastError());
1093 if (!result) return;
1095 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1096 ok(result, "%08x\n", GetLastError());
1097 if (!result) return;
1099 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1100 * the OID at all. */
1101 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1102 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1103 if (result) return;*/
1105 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1106 ok(result, "%08x\n", GetLastError());
1107 if (!result) return;
1109 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1110 ok(result, "%08x\n", GetLastError());
1111 if (!result) return;
1113 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1114 ok(result, "%08x\n", GetLastError());
1115 if (!result) return;
1117 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1118 ok(result, "%08x\n", GetLastError());
1119 if (!result) return;
1121 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1122 ok(result, "%08x\n", GetLastError());
1123 if (!result) return;
1125 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1126 ok(result, "%08x\n", GetLastError());
1127 if (!result) return;
1129 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1130 ok(result, "%08x\n", GetLastError());
1131 if (!result) return;
1133 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1134 ok(result, "%08x\n", GetLastError());
1135 if (!result) return;
1137 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1138 ok(result, "%08x\n", GetLastError());
1139 if (!result) return;
1141 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1142 ok(result, "%08x\n", GetLastError());
1143 if (!result) return;
1145 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1146 ok(result, "%08x\n", GetLastError());
1147 if (!result) return;
1149 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1150 ok(result, "%08x\n", GetLastError());
1151 if (!result) return;
1154 static void test_rsa_encrypt(void)
1157 BYTE abData[2048] = "Wine rocks!";
1161 /* It is allowed to use the key exchange key for encryption/decryption */
1162 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1163 ok (result, "%08x\n", GetLastError());
1164 if (!result) return;
1167 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1168 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1169 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1171 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1172 ok (result, "%08x\n", GetLastError());
1173 if (!result) return;
1175 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1176 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1178 CryptDestroyKey(hRSAKey);
1180 /* It is not allowed to use the signature key for encryption/decryption */
1181 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1182 ok (result, "%08x\n", GetLastError());
1183 if (!result) return;
1186 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1187 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1189 CryptDestroyKey(hRSAKey);
1192 static void test_import_export(void)
1194 DWORD dwLen, dwDataLen;
1195 HCRYPTKEY hPublicKey;
1198 BYTE emptyKey[2048];
1199 static BYTE abPlainPublicKey[84] = {
1200 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1201 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1202 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1203 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1204 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1205 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1206 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1207 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1208 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1209 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1210 0x11, 0x11, 0x11, 0x11
1214 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1215 ok(result, "failed to import the public key\n");
1217 dwDataLen=sizeof(algID);
1218 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1219 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1220 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1222 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1223 ok(result, "failed to export the fresh imported public key\n");
1224 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1225 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1228 static void test_schannel_provider(void)
1231 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1232 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1235 SCHANNEL_ALG saSChannelAlg;
1236 CRYPT_DATA_BLOB data_blob;
1237 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1238 BYTE abPlainPrivateKey[596] = {
1239 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1240 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1241 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1242 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1243 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1244 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1245 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1246 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1247 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1248 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1249 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1250 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1251 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1252 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1253 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1254 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1255 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1256 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1257 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1258 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1259 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1260 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1261 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1262 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1263 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1264 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1265 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1266 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1267 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1268 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1269 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1270 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1271 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1272 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1273 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1274 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1275 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1276 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1277 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1278 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1279 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1280 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1281 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1282 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1283 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1284 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1285 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1286 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1287 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1288 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1289 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1290 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1291 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1292 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1293 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1294 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1295 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1296 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1297 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1298 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1299 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1300 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1301 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1302 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1303 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1304 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1305 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1306 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1307 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1308 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1309 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1310 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1311 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1312 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1313 0xf2, 0x5d, 0x58, 0x07
1315 BYTE abTLS1Master[140] = {
1316 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1317 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1318 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1319 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1320 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1321 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1322 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1323 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1324 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1325 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1326 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1327 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1328 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1329 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1330 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1331 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1332 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1333 0xd3, 0x1e, 0x82, 0xb3
1335 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1336 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1337 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1338 BYTE abClientFinished[16] = "client finished";
1339 BYTE abData[16] = "Wine rocks!";
1341 static const BYTE abEncryptedData[16] = {
1342 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1343 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1345 static const BYTE abPRF[16] = {
1346 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1347 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1349 static const BYTE abMD5[16] = {
1350 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1351 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1354 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1355 ok (result, "%08x\n", GetLastError());
1357 CryptReleaseContext(hProv, 0);
1359 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1360 ok (result, "%08x\n", GetLastError());
1361 if (!result) return;
1363 /* To get deterministic results, we import the TLS1 master secret (which
1364 * is typically generated from a random generator). Therefore, we need
1366 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1367 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1368 ok (result, "%08x\n", GetLastError());
1369 if (!result) return;
1371 dwLen = (DWORD)sizeof(abTLS1Master);
1372 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1373 ok (result, "%08x\n", GetLastError());
1374 if (!result) return;
1376 /* Setting the TLS1 client and server random parameters, as well as the
1377 * MAC and encryption algorithm parameters. */
1378 data_blob.cbData = 33;
1379 data_blob.pbData = abClientSecret;
1380 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1381 ok (result, "%08x\n", GetLastError());
1382 if (!result) return;
1384 data_blob.cbData = 33;
1385 data_blob.pbData = abServerSecret;
1386 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1387 ok (result, "%08x\n", GetLastError());
1388 if (!result) return;
1390 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1391 saSChannelAlg.Algid = CALG_DES;
1392 saSChannelAlg.cBits = 64;
1393 saSChannelAlg.dwFlags = 0;
1394 saSChannelAlg.dwReserved = 0;
1395 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1396 ok (result, "%08x\n", GetLastError());
1397 if (!result) return;
1399 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1400 saSChannelAlg.Algid = CALG_MD5;
1401 saSChannelAlg.cBits = 128;
1402 saSChannelAlg.dwFlags = 0;
1403 saSChannelAlg.dwReserved = 0;
1404 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1405 ok (result, "%08x\n", GetLastError());
1406 if (!result) return;
1408 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1409 * (Keys can only be derived from hashes, not from other keys.) */
1410 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1411 ok (result, "%08x\n", GetLastError());
1412 if (!result) return;
1414 /* Deriving the server write encryption key from the master hash */
1415 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1416 ok (result, "%08x\n", GetLastError());
1417 if (!result) return;
1419 /* Encrypting some data with the server write encryption key and checking the result. */
1421 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1422 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1424 /* Second test case: Test the TLS1 pseudo random number function. */
1425 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1426 ok (result, "%08x\n", GetLastError());
1427 if (!result) return;
1429 /* Set the label and seed parameters for the random number function */
1430 data_blob.cbData = 36;
1431 data_blob.pbData = abHashedHandshakes;
1432 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1433 ok (result, "%08x\n", GetLastError());
1434 if (!result) return;
1436 data_blob.cbData = 15;
1437 data_blob.pbData = abClientFinished;
1438 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1439 ok (result, "%08x\n", GetLastError());
1440 if (!result) return;
1442 /* Generate some pseudo random bytes and check if they are correct. */
1443 dwLen = (DWORD)sizeof(abData);
1444 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1445 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1446 "%08x\n", GetLastError());
1448 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1449 * Hash some data with the HMAC. Compare results. */
1450 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1451 ok (result, "%08x\n", GetLastError());
1452 if (!result) return;
1454 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1455 ok (result, "%08x\n", GetLastError());
1456 if (!result) return;
1458 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1459 ok (result, "%08x\n", GetLastError());
1460 if (!result) return;
1462 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1463 ok (result, "%08x\n", GetLastError());
1464 if (!result) return;
1466 dwLen = (DWORD)sizeof(abMD5Hash);
1467 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1468 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1470 CryptDestroyHash(hHMAC);
1471 CryptDestroyHash(hTLS1PRF);
1472 CryptDestroyHash(hMasterHash);
1473 CryptDestroyKey(hServerWriteMACKey);
1474 CryptDestroyKey(hServerWriteKey);
1475 CryptDestroyKey(hRSAKey);
1476 CryptDestroyKey(hMasterSecret);
1477 CryptReleaseContext(hProv, 0);
1478 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1481 static void test_enum_container(void)
1483 BYTE abContainerName[256];
1485 BOOL result, fFound = FALSE;
1487 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1488 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1489 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1490 ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1492 /* If the result fits into abContainerName dwBufferLen is left untouched */
1493 dwBufferLen = (DWORD)sizeof(abContainerName);
1494 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1495 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1497 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1499 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1500 dwBufferLen = (DWORD)sizeof(abContainerName);
1501 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1503 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1506 static BYTE signBlob[] = {
1507 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1508 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1509 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1510 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1511 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1512 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1513 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1514 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1515 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1516 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1517 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1518 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1519 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1520 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1521 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1522 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1523 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1524 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1525 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1526 0xb6,0x85,0x86,0x07 };
1528 static void test_null_provider(void)
1533 DWORD keySpec, dataLen,dwParam;
1534 char szName[MAX_PATH];
1536 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1537 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1538 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1539 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1540 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1541 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1542 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1543 CRYPT_DELETEKEYSET);
1544 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1545 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1546 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1547 CRYPT_DELETEKEYSET);
1548 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1549 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1550 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1551 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1552 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1554 /* Delete the default container. */
1555 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1556 /* Once you've deleted the default container you can't open it as if it
1559 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1560 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1561 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1562 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1563 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1564 CRYPT_VERIFYCONTEXT);
1565 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1566 if (!result) return;
1567 dataLen = sizeof(keySpec);
1568 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1570 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1571 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1572 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1573 * supported, you can't get the keys from this container.
1575 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1576 ok(!result && GetLastError() == NTE_NO_KEY,
1577 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1578 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1579 ok(!result && GetLastError() == NTE_NO_KEY,
1580 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1581 result = CryptReleaseContext(prov, 0);
1582 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1583 /* You can create a new default container. */
1584 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1586 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1587 /* But you still can't get the keys (until one's been generated.) */
1588 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1589 ok(!result && GetLastError() == NTE_NO_KEY,
1590 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1591 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1592 ok(!result && GetLastError() == NTE_NO_KEY,
1593 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1594 CryptReleaseContext(prov, 0);
1595 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1597 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1598 CRYPT_DELETEKEYSET);
1599 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1600 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1601 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1602 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1603 CRYPT_VERIFYCONTEXT);
1604 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1605 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1606 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1608 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1609 if (!result) return;
1610 /* Test provider parameters getter */
1611 dataLen = sizeof(dwParam);
1612 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1613 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1614 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1615 dataLen = sizeof(dwParam);
1616 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1617 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1618 "Expected 0, got 0x%08X\n",dwParam);
1619 dataLen = sizeof(dwParam);
1620 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1621 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1622 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1623 dataLen = sizeof(keySpec);
1624 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1625 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1626 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1627 /* PP_CONTAINER parameter */
1628 dataLen = sizeof(szName);
1629 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1630 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1631 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1632 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1633 /* PP_UNIQUE_CONTAINER parameter */
1634 dataLen = sizeof(szName);
1635 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1636 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1637 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1638 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1639 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1640 ok(!result && GetLastError() == NTE_NO_KEY,
1641 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1642 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1643 ok(!result && GetLastError() == NTE_NO_KEY,
1644 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1646 /* Importing a key exchange blob.. */
1647 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1649 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1650 CryptDestroyKey(key);
1651 /* allows access to the key exchange key.. */
1652 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1653 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1654 CryptDestroyKey(key);
1655 /* but not to the private key. */
1656 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1657 ok(!result && GetLastError() == NTE_NO_KEY,
1658 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1659 CryptReleaseContext(prov, 0);
1660 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1661 CRYPT_DELETEKEYSET);
1663 /* Whereas importing a sign blob.. */
1664 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1666 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1667 if (!result) return;
1668 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1669 ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1670 /* doesn't allow access to the key exchange key.. */
1671 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1672 ok(!result && GetLastError() == NTE_NO_KEY,
1673 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1674 /* but does to the private key. */
1675 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1676 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1677 CryptDestroyKey(key);
1679 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1680 CRYPT_DELETEKEYSET);
1683 /* test for the bug in accessing the user key in a container
1685 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1687 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1688 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1689 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1690 CryptDestroyKey(key);
1691 CryptReleaseContext(prov,0);
1692 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1693 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1694 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1695 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1696 CryptDestroyKey(key);
1698 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1699 CRYPT_DELETEKEYSET);
1701 /* test the machine key set */
1702 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1703 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1704 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1705 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1706 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1707 CryptReleaseContext(prov, 0);
1708 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1709 CRYPT_MACHINE_KEYSET);
1710 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1711 CryptReleaseContext(prov,0);
1712 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1713 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1714 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1716 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1717 CRYPT_MACHINE_KEYSET);
1718 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1719 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1725 if (!init_environment())
1737 test_block_cipher_modes();
1738 test_import_private();
1739 test_verify_signature();
1741 test_import_export();
1742 test_enum_container();
1743 clean_up_environment();
1744 test_schannel_provider();
1745 test_null_provider();