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, %08lx\n", result, GetLastError());
66 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
68 ok(GetLastError()==NTE_BAD_KEYSET, "%08lx\n", GetLastError());
69 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
70 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
72 ok(result, "%08lx\n", GetLastError());
73 if (!result) return 0;
74 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
75 ok(result, "%08lx\n", GetLastError());
76 if (result) CryptDestroyKey(hKey);
77 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
78 ok(result, "%08lx\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, "%08lx\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, "%08lx, %ld\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, "%08lx, %ld\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, "%08lx\n", GetLastError());
124 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
125 ok(result, "%08lx\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, "%08lx\n", GetLastError());
145 ok(result, "%08lx\n", GetLastError());
146 if (!result) return FALSE;
147 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
148 ok(result, "%08lx\n", GetLastError());
149 if (!result) return FALSE;
150 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
151 ok(result, "%08lx\n", GetLastError());
152 if (!result) return FALSE;
154 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
155 ok(result, "%08lx\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 md5hash[16] = {
169 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
170 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
171 static const unsigned char sha1hash[20] = {
172 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
173 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
174 unsigned char pbData[2048];
176 HCRYPTHASH hHash, hHashClone;
177 BYTE pbHashValue[36];
181 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
184 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
186 /* rsaenh compiled without OpenSSL */
187 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
189 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
190 ok(result, "%08lx\n", GetLastError());
193 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
194 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
197 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
198 ok(result, "%08lx\n", GetLastError());
200 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
202 result = CryptDestroyHash(hHash);
203 ok(result, "%08lx\n", GetLastError());
207 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
208 ok(result, "%08lx\n", GetLastError());
210 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
211 ok(result, "%08lx\n", GetLastError());
214 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
215 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
218 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
219 ok(result, "%08lx\n", GetLastError());
221 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
223 result = CryptDestroyHash(hHash);
224 ok(result, "%08lx\n", GetLastError());
227 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
228 ok(result, "%08lx\n", GetLastError());
230 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
231 ok(result, "%08lx\n", GetLastError());
234 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
235 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
238 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
239 ok(result, "%08lx\n", GetLastError());
241 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
243 result = CryptDestroyHash(hHash);
244 ok(result, "%08lx\n", GetLastError());
247 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
248 ok(result, "%08lx\n", GetLastError());
250 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
251 ok(result, "%08lx\n", GetLastError());
253 if(pCryptDuplicateHash) {
254 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
255 ok(result, "%08lx\n", GetLastError());
257 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
258 ok(result, "%08lx\n", GetLastError());
261 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
262 ok(result && (hashlen == 20), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
265 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
266 ok(result, "%08lx\n", GetLastError());
268 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
270 result = CryptDestroyHash(hHashClone);
271 ok(result, "%08lx\n", GetLastError());
274 result = CryptDestroyHash(hHash);
275 ok(result, "%08lx\n", GetLastError());
278 static void test_block_cipher_modes(void)
280 static const BYTE plain[23] = {
281 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
282 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
283 static const BYTE ecb[24] = {
284 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
285 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
286 static const BYTE cbc[24] = {
287 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
288 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
289 static const BYTE cfb[24] = {
290 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
291 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
297 result = derive_key(CALG_RC2, &hKey, 40);
300 memcpy(abData, plain, sizeof(abData));
302 dwMode = CRYPT_MODE_ECB;
303 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
304 ok(result, "%08lx\n", GetLastError());
307 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
308 ok(result, "CryptEncrypt failed: %08lx\n", GetLastError());
309 ok(dwLen == 24, "Unexpected length %ld\n", dwLen);
311 SetLastError(ERROR_SUCCESS);
313 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
314 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
315 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
317 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
318 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
319 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
321 dwMode = CRYPT_MODE_CBC;
322 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
323 ok(result, "%08lx\n", GetLastError());
326 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
327 ok(result, "CryptEncrypt failed: %08lx\n", GetLastError());
328 ok(dwLen == 24, "Unexpected length %ld\n", dwLen);
331 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
332 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
333 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
335 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
336 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
337 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
339 dwMode = CRYPT_MODE_CFB;
340 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
341 ok(result, "%08lx\n", GetLastError());
344 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
345 ok(result && dwLen == 16, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
348 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
349 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
350 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
353 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
354 ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
357 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
358 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
359 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
361 dwMode = CRYPT_MODE_OFB;
362 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
363 ok(result, "%08lx\n", GetLastError());
366 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
367 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
370 static void test_3des112(void)
375 unsigned char pbData[16];
378 result = derive_key(CALG_3DES_112, &hKey, 0);
380 /* rsaenh compiled without OpenSSL */
381 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
385 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
388 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
389 ok(result, "%08lx\n", GetLastError());
391 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
392 ok(result, "%08lx\n", GetLastError());
394 result = CryptDestroyKey(hKey);
395 ok(result, "%08lx\n", GetLastError());
398 static void test_des(void)
403 unsigned char pbData[16];
406 result = derive_key(CALG_DES, &hKey, 56);
408 /* rsaenh compiled without OpenSSL */
409 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
413 dwMode = CRYPT_MODE_ECB;
414 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
415 ok(result, "%08lx\n", GetLastError());
417 dwLen = sizeof(DWORD);
418 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
419 ok(result, "%08lx\n", GetLastError());
421 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
424 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
425 ok(result, "%08lx\n", GetLastError());
427 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
428 ok(result, "%08lx\n", GetLastError());
430 result = CryptDestroyKey(hKey);
431 ok(result, "%08lx\n", GetLastError());
434 static void test_3des(void)
439 unsigned char pbData[16];
440 static const BYTE des3[16] = {
441 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
442 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
445 result = derive_key(CALG_3DES, &hKey, 0);
448 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
451 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
452 ok(result, "%08lx\n", GetLastError());
454 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
456 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
457 ok(result, "%08lx\n", GetLastError());
459 result = CryptDestroyKey(hKey);
460 ok(result, "%08lx\n", GetLastError());
463 static void test_rc2(void)
465 static const BYTE rc2encrypted[16] = {
466 0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
467 0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
471 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
473 unsigned char pbData[2000], pbHashValue[16];
476 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
479 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
481 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
483 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
484 ok(result, "%08lx\n", GetLastError());
487 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
488 ok(result, "%08lx\n", GetLastError());
490 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
491 ok(result, "%08lx\n", GetLastError());
493 dwLen = sizeof(DWORD);
494 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
495 ok(result, "%08lx\n", GetLastError());
497 dwMode = CRYPT_MODE_CBC;
498 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
499 ok(result, "%08lx\n", GetLastError());
501 dwLen = sizeof(DWORD);
502 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
503 ok(result, "%08lx\n", GetLastError());
505 dwLen = sizeof(DWORD);
506 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
507 ok(result, "%08lx\n", GetLastError());
509 dwLen = sizeof(DWORD);
510 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
511 ok(result, "%08lx\n", GetLastError());
513 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
514 ok(result, "%08lx\n", GetLastError());
515 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
516 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
517 HeapFree(GetProcessHeap(), 0, pbTemp);
519 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
520 ok(result, "%08lx\n", GetLastError());
521 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
522 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
523 HeapFree(GetProcessHeap(), 0, pbTemp);
525 dwLen = sizeof(DWORD);
526 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
528 result = CryptDestroyHash(hHash);
529 ok(result, "%08lx\n", GetLastError());
532 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
533 ok(result, "%08lx\n", GetLastError());
535 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
537 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
538 ok(result, "%08lx\n", GetLastError());
539 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
540 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
541 HeapFree(GetProcessHeap(), 0, pbTemp);
543 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
544 ok(result, "%08lx\n", GetLastError());
546 result = CryptDestroyKey(hKey);
547 ok(result, "%08lx\n", GetLastError());
551 static void test_rc4(void)
553 static const BYTE rc4[16] = {
554 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
555 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
559 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
560 unsigned char pbData[2000], *pbTemp;
561 unsigned char pszBuffer[256];
564 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
567 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
569 /* rsaenh compiled without OpenSSL */
570 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
572 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
573 ok(result, "%08lx\n", GetLastError());
576 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
577 ok(result, "%08lx\n", GetLastError());
579 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
580 ok(result, "%08lx\n", GetLastError());
582 dwLen = sizeof(DWORD);
583 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
584 ok(result, "%08lx\n", GetLastError());
586 dwLen = sizeof(DWORD);
587 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
588 ok(result, "%08lx\n", GetLastError());
590 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
591 ok(result, "%08lx\n", GetLastError());
592 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
593 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
594 HeapFree(GetProcessHeap(), 0, pbTemp);
596 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
597 ok(result, "%08lx\n", GetLastError());
598 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
599 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
600 HeapFree(GetProcessHeap(), 0, pbTemp);
602 dwLen = sizeof(DWORD);
603 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
605 result = CryptDestroyHash(hHash);
606 ok(result, "%08lx\n", GetLastError());
609 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
610 ok(result, "%08lx\n", GetLastError());
612 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
613 ok(result, "%08lx\n", GetLastError());
615 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
617 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
618 ok(result, "%08lx\n", GetLastError());
620 result = CryptDestroyKey(hKey);
621 ok(result, "%08lx\n", GetLastError());
625 static void test_hmac(void) {
629 HMAC_INFO hmacInfo = { CALG_MD2, NULL, 0, NULL, 0 };
632 static const BYTE hmac[16] = {
633 0xfd, 0x16, 0xb5, 0xb6, 0x13, 0x1c, 0x2b, 0xd6,
634 0x0a, 0xc7, 0xae, 0x92, 0x76, 0xa3, 0x05, 0x71 };
637 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
639 if (!derive_key(CALG_RC2, &hKey, 56)) return;
641 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
642 ok(result, "%08lx\n", GetLastError());
645 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
646 ok(result, "%08lx\n", GetLastError());
648 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
649 ok(result, "%08lx\n", GetLastError());
651 dwLen = sizeof(abData)/sizeof(BYTE);
652 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
653 ok(result, "%08lx\n", GetLastError());
655 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
657 result = CryptDestroyHash(hHash);
658 ok(result, "%08lx\n", GetLastError());
660 result = CryptDestroyKey(hKey);
661 ok(result, "%08lx\n", GetLastError());
664 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
665 ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
668 static void test_mac(void) {
673 BYTE abData[256], abEnc[264];
674 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
677 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
678 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
680 if (!derive_key(CALG_RC2, &hKey, 56)) return;
683 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
684 ok (result && dwLen == 264, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
686 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
687 ok(result, "%08lx\n", GetLastError());
690 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
691 ok(result, "%08lx\n", GetLastError());
693 dwLen = sizeof(abData)/sizeof(BYTE);
694 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
695 ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
697 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
699 result = CryptDestroyHash(hHash);
700 ok(result, "%08lx\n", GetLastError());
702 result = CryptDestroyKey(hKey);
703 ok(result, "%08lx\n", GetLastError());
706 if (!derive_key(CALG_RC4, &hKey, 56)) return;
708 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
709 ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
711 result = CryptDestroyKey(hKey);
712 ok(result, "%08lx\n", GetLastError());
715 static BYTE abPlainPrivateKey[596] = {
716 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
717 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
718 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
719 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
720 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
721 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
722 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
723 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
724 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
725 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
726 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
727 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
728 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
729 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
730 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
731 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
732 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
733 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
734 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
735 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
736 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
737 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
738 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
739 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
740 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
741 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
742 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
743 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
744 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
745 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
746 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
747 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
748 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
749 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
750 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
751 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
752 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
753 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
754 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
755 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
756 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
757 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
758 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
759 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
760 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
761 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
762 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
763 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
764 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
765 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
766 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
767 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
768 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
769 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
770 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
771 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
772 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
773 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
774 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
775 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
776 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
777 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
778 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
779 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
780 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
781 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
782 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
783 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
784 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
785 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
786 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
787 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
788 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
789 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
790 0xf2, 0x5d, 0x58, 0x07
793 static void test_import_private(void)
796 HCRYPTKEY hKeyExchangeKey, hSessionKey;
798 static BYTE abSessionKey[148] = {
799 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
800 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
801 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
802 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
803 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
804 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
805 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
806 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
807 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
808 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
809 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
810 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
811 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
812 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
813 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
814 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
815 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
816 0x04, 0x8c, 0x49, 0x92
818 static BYTE abEncryptedMessage[12] = {
819 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
820 0x1c, 0xfd, 0xde, 0x71
823 dwLen = (DWORD)sizeof(abPlainPrivateKey);
824 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
826 /* rsaenh compiled without OpenSSL */
827 ok(GetLastError() == NTE_FAIL, "%08lx\n", GetLastError());
831 dwLen = (DWORD)sizeof(abSessionKey);
832 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
833 ok(result, "%08lx\n", GetLastError());
836 dwLen = (DWORD)sizeof(abEncryptedMessage);
837 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
838 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
839 "%08lx, len: %ld\n", GetLastError(), dwLen);
841 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
843 dwLen = (DWORD)sizeof(abSessionKey);
844 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
845 ok(result, "%08lx\n", GetLastError());
848 dwLen = (DWORD)sizeof(abSessionKey);
849 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
850 ok(result, "%08lx\n", GetLastError());
854 static void test_verify_signature(void) {
856 HCRYPTKEY hPubSignKey;
857 BYTE abData[] = "Wine rocks!";
859 BYTE abPubKey[148] = {
860 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
861 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
862 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
863 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
864 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
865 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
866 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
867 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
868 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
869 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
870 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
871 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
872 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
873 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
874 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
875 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
876 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
877 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
878 0xe1, 0x21, 0x50, 0xac
880 /* md2 with hash oid */
881 BYTE abSignatureMD2[128] = {
882 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
883 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
884 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
885 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
886 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
887 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
888 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
889 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
890 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
891 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
892 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
893 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
894 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
895 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
896 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
897 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
899 /* md2 without hash oid */
900 BYTE abSignatureMD2NoOID[128] = {
901 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
902 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
903 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
904 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
905 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
906 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
907 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
908 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
909 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
910 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
911 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
912 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
913 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
914 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
915 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
916 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
918 /* md4 with hash oid */
919 BYTE abSignatureMD4[128] = {
920 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
921 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
922 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
923 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
924 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
925 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
926 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
927 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
928 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
929 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
930 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
931 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
932 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
933 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
934 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
935 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
937 /* md4 without hash oid */
938 BYTE abSignatureMD4NoOID[128] = {
939 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
940 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
941 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
942 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
943 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
944 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
945 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
946 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
947 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
948 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
949 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
950 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
951 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
952 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
953 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
954 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
956 /* md5 with hash oid */
957 BYTE abSignatureMD5[128] = {
958 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
959 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
960 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
961 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
962 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
963 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
964 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
965 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
966 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
967 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
968 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
969 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
970 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
971 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
972 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
973 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
975 /* md5 without hash oid */
976 BYTE abSignatureMD5NoOID[128] = {
977 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
978 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
979 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
980 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
981 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
982 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
983 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
984 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
985 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
986 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
987 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
988 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
989 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
990 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
991 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
992 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
994 /* sha with hash oid */
995 BYTE abSignatureSHA[128] = {
996 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
997 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
998 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
999 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1000 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1001 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1002 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1003 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1004 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1005 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1006 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1007 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1008 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1009 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1010 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1011 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1013 /* sha without hash oid */
1014 BYTE abSignatureSHANoOID[128] = {
1015 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1016 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1017 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1018 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1019 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1020 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1021 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1022 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1023 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1024 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1025 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1026 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1027 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1028 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1029 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1030 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1033 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1034 ok(result, "%08lx\n", GetLastError());
1035 if (!result) return;
1037 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1038 ok(result, "%08lx\n", GetLastError());
1039 if (!result) return;
1041 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1042 ok(result, "%08lx\n", GetLastError());
1043 if (!result) return;
1045 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1046 ok(result, "%08lx\n", GetLastError());
1047 if (!result) return;
1049 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1050 ok(result, "%08lx\n", GetLastError());
1051 if (!result) return;
1053 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1054 * the OID at all. */
1055 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1056 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1057 if (result) return;*/
1059 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1060 ok(result, "%08lx\n", GetLastError());
1061 if (!result) return;
1063 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1064 ok(result, "%08lx\n", GetLastError());
1065 if (!result) return;
1067 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1068 ok(result, "%08lx\n", GetLastError());
1069 if (!result) return;
1071 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1072 ok(result, "%08lx\n", GetLastError());
1073 if (!result) return;
1075 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1076 ok(result, "%08lx\n", GetLastError());
1077 if (!result) return;
1079 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1080 ok(result, "%08lx\n", GetLastError());
1081 if (!result) return;
1083 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1084 ok(result, "%08lx\n", GetLastError());
1085 if (!result) return;
1087 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1088 ok(result, "%08lx\n", GetLastError());
1089 if (!result) return;
1091 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1092 ok(result, "%08lx\n", GetLastError());
1093 if (!result) return;
1095 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1096 ok(result, "%08lx\n", GetLastError());
1097 if (!result) return;
1099 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1100 ok(result, "%08lx\n", GetLastError());
1101 if (!result) return;
1103 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1104 ok(result, "%08lx\n", GetLastError());
1105 if (!result) return;
1108 static void test_rsa_encrypt(void)
1111 BYTE abData[2048] = "Wine rocks!";
1115 /* It is allowed to use the key exchange key for encryption/decryption */
1116 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1117 ok (result, "%08lx\n", GetLastError());
1118 if (!result) return;
1121 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1122 ok(result, "CryptEncrypt failed: %08lx\n", GetLastError());
1123 ok(dwLen == 128, "Unexpected length %ld\n", dwLen);
1125 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1126 ok (result, "%08lx\n", GetLastError());
1127 if (!result) return;
1129 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1130 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08lx\n", GetLastError());
1132 CryptDestroyKey(hRSAKey);
1134 /* It is not allowed to use the signature key for encryption/decryption */
1135 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1136 ok (result, "%08lx\n", GetLastError());
1137 if (!result) return;
1140 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1141 ok (!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
1143 CryptDestroyKey(hRSAKey);
1146 static void test_import_export(void)
1148 DWORD dwLen, dwDataLen;
1149 HCRYPTKEY hPublicKey;
1152 BYTE emptyKey[2048];
1153 static BYTE abPlainPublicKey[84] = {
1154 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1155 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1156 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1157 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1158 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1159 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1160 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1161 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1162 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1163 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1164 0x11, 0x11, 0x11, 0x11
1168 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1169 ok(result, "failed to import the public key\n");
1171 dwDataLen=sizeof(algID);
1172 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1173 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1174 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1176 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1177 ok(result, "failed to export the fresh imported public key\n");
1178 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %ld bytes.\n",dwLen);
1179 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1182 static void test_schannel_provider(void)
1185 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1186 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1189 SCHANNEL_ALG saSChannelAlg;
1190 CRYPT_DATA_BLOB data_blob;
1191 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1192 BYTE abPlainPrivateKey[596] = {
1193 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1194 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1195 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1196 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1197 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1198 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1199 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1200 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1201 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1202 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1203 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1204 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1205 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1206 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1207 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1208 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1209 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1210 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1211 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1212 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1213 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1214 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1215 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1216 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1217 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1218 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1219 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1220 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1221 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1222 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1223 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1224 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1225 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1226 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1227 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1228 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1229 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1230 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1231 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1232 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1233 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1234 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1235 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1236 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1237 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1238 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1239 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1240 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1241 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1242 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1243 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1244 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1245 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1246 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1247 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1248 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1249 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1250 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1251 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1252 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1253 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1254 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1255 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1256 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1257 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1258 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1259 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1260 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1261 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1262 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1263 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1264 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1265 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1266 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1267 0xf2, 0x5d, 0x58, 0x07
1269 BYTE abTLS1Master[140] = {
1270 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1271 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1272 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1273 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1274 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1275 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1276 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1277 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1278 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1279 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1280 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1281 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1282 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1283 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1284 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1285 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1286 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1287 0xd3, 0x1e, 0x82, 0xb3
1289 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1290 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1291 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1292 BYTE abClientFinished[16] = "client finished";
1293 BYTE abData[16] = "Wine rocks!";
1295 static const BYTE abEncryptedData[16] = {
1296 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1297 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1299 static const BYTE abPRF[16] = {
1300 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1301 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1303 static const BYTE abMD5[16] = {
1304 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1305 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1308 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1309 ok (result, "%08lx\n", GetLastError());
1310 if (!result) return;
1312 /* To get deterministic results, we import the TLS1 master secret (which
1313 * is typically generated from a random generator). Therefore, we need
1315 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1316 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1317 ok (result, "%08lx\n", GetLastError());
1318 if (!result) return;
1320 dwLen = (DWORD)sizeof(abTLS1Master);
1321 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1322 ok (result, "%08lx\n", GetLastError());
1323 if (!result) return;
1325 /* Setting the TLS1 client and server random parameters, as well as the
1326 * MAC and encryption algorithm parameters. */
1327 data_blob.cbData = 33;
1328 data_blob.pbData = abClientSecret;
1329 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1330 ok (result, "%08lx\n", GetLastError());
1331 if (!result) return;
1333 data_blob.cbData = 33;
1334 data_blob.pbData = abServerSecret;
1335 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1336 ok (result, "%08lx\n", GetLastError());
1337 if (!result) return;
1339 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1340 saSChannelAlg.Algid = CALG_DES;
1341 saSChannelAlg.cBits = 64;
1342 saSChannelAlg.dwFlags = 0;
1343 saSChannelAlg.dwReserved = 0;
1344 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1345 ok (result, "%08lx\n", GetLastError());
1346 if (!result) return;
1348 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1349 saSChannelAlg.Algid = CALG_MD5;
1350 saSChannelAlg.cBits = 128;
1351 saSChannelAlg.dwFlags = 0;
1352 saSChannelAlg.dwReserved = 0;
1353 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1354 ok (result, "%08lx\n", GetLastError());
1355 if (!result) return;
1357 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1358 * (Keys can only be derived from hashes, not from other keys.) */
1359 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1360 ok (result, "%08lx\n", GetLastError());
1361 if (!result) return;
1363 /* Deriving the server write encryption key from the master hash */
1364 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1365 ok (result, "%08lx\n", GetLastError());
1366 if (!result) return;
1368 /* Encrypting some data with the server write encryption key and checking the result. */
1370 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1371 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08lx\n", GetLastError());
1373 /* Second test case: Test the TLS1 pseudo random number function. */
1374 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1375 ok (result, "%08lx\n", GetLastError());
1376 if (!result) return;
1378 /* Set the label and seed parameters for the random number function */
1379 data_blob.cbData = 36;
1380 data_blob.pbData = abHashedHandshakes;
1381 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1382 ok (result, "%08lx\n", GetLastError());
1383 if (!result) return;
1385 data_blob.cbData = 15;
1386 data_blob.pbData = abClientFinished;
1387 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1388 ok (result, "%08lx\n", GetLastError());
1389 if (!result) return;
1391 /* Generate some pseudo random bytes and check if they are correct. */
1392 dwLen = (DWORD)sizeof(abData);
1393 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1394 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1395 "%08lx\n", GetLastError());
1397 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1398 * Hash some data with the HMAC. Compare results. */
1399 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1400 ok (result, "%08lx\n", GetLastError());
1401 if (!result) return;
1403 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1404 ok (result, "%08lx\n", GetLastError());
1405 if (!result) return;
1407 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1408 ok (result, "%08lx\n", GetLastError());
1409 if (!result) return;
1411 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1412 ok (result, "%08lx\n", GetLastError());
1413 if (!result) return;
1415 dwLen = (DWORD)sizeof(abMD5Hash);
1416 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1417 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08lx\n", GetLastError());
1419 CryptDestroyHash(hHMAC);
1420 CryptDestroyHash(hTLS1PRF);
1421 CryptDestroyHash(hMasterHash);
1422 CryptDestroyKey(hServerWriteMACKey);
1423 CryptDestroyKey(hServerWriteKey);
1424 CryptDestroyKey(hRSAKey);
1425 CryptDestroyKey(hMasterSecret);
1426 CryptReleaseContext(hProv, 0);
1427 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1430 static void test_enum_container(void)
1432 BYTE abContainerName[256];
1434 BOOL result, fFound = FALSE;
1436 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1437 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1438 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1439 ok (result && dwBufferLen == MAX_PATH + 1, "%08lx\n", GetLastError());
1441 /* If the result fits into abContainerName dwBufferLen is left untouched */
1442 dwBufferLen = (DWORD)sizeof(abContainerName);
1443 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1444 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08lx\n", GetLastError());
1446 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1448 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1449 dwBufferLen = (DWORD)sizeof(abContainerName);
1450 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1452 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08lx\n", fFound, GetLastError());
1455 static BYTE signBlob[] = {
1456 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1457 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1458 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1459 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1460 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1461 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1462 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1463 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1464 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1465 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1466 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1467 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1468 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1469 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1470 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1471 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1472 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1473 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1474 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1475 0xb6,0x85,0x86,0x07 };
1477 static void test_null_provider(void)
1482 DWORD keySpec, dataLen;
1484 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1485 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1486 "Expected NTE_BAD_PROV_TYPE, got %08lx\n", GetLastError());
1487 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1488 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1489 "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
1490 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1491 CRYPT_DELETEKEYSET);
1492 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1493 "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
1494 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1495 CRYPT_DELETEKEYSET);
1496 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1497 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
1498 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1499 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1500 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
1502 /* Delete the default container. */
1503 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1504 /* Once you've deleted the default container you can't open it as if it
1507 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1508 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1509 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
1510 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1511 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1512 CRYPT_VERIFYCONTEXT);
1513 ok(result, "CryptAcquireContext failed: %08lx\n", GetLastError());
1514 if (!result) return;
1515 dataLen = sizeof(keySpec);
1516 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1518 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1519 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08lx\n", keySpec);
1520 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1521 * supported, you can't get the keys from this container.
1523 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1524 ok(!result && GetLastError() == NTE_NO_KEY,
1525 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1526 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1527 ok(!result && GetLastError() == NTE_NO_KEY,
1528 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1529 result = CryptReleaseContext(prov, 0);
1530 ok(result, "CryptReleaseContext failed: %08lx\n", GetLastError());
1531 /* You can create a new default container. */
1532 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1534 ok(result, "CryptAcquireContext failed: %08lx\n", GetLastError());
1535 /* But you still can't get the keys (until one's been generated.) */
1536 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1537 ok(!result && GetLastError() == NTE_NO_KEY,
1538 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1539 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1540 ok(!result && GetLastError() == NTE_NO_KEY,
1541 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1542 CryptReleaseContext(prov, 0);
1543 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1545 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1546 CRYPT_DELETEKEYSET);
1547 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1548 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1549 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
1550 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1551 CRYPT_VERIFYCONTEXT);
1552 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1553 "Expected NTE_BAD_FLAGS, got %08lx\n", GetLastError());
1554 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1556 ok(result, "CryptAcquireContext failed: %08lx\n", GetLastError());
1557 if (!result) return;
1558 dataLen = sizeof(keySpec);
1559 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1561 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1562 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08lx\n", keySpec);
1563 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1564 ok(!result && GetLastError() == NTE_NO_KEY,
1565 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1566 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1567 ok(!result && GetLastError() == NTE_NO_KEY,
1568 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1570 /* Importing a key exchange blob.. */
1571 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1573 ok(result, "CryptImportKey failed: %08lx\n", GetLastError());
1574 CryptDestroyKey(key);
1575 /* allows access to the key exchange key.. */
1576 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1577 ok(result, "CryptGetUserKey failed: %08lx\n", GetLastError());
1578 CryptDestroyKey(key);
1579 /* but not to the private key. */
1580 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1581 ok(!result && GetLastError() == NTE_NO_KEY,
1582 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1583 CryptReleaseContext(prov, 0);
1584 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1585 CRYPT_DELETEKEYSET);
1587 /* Whereas importing a sign blob.. */
1588 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1590 ok(result, "CryptAcquireContext failed: %08lx\n", GetLastError());
1591 if (!result) return;
1592 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1593 ok(result, "CryptGenKey failed: %08lx\n", GetLastError());
1594 /* doesn't allow access to the key exchange key.. */
1595 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1596 ok(!result && GetLastError() == NTE_NO_KEY,
1597 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
1598 /* but does to the private key. */
1599 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1600 ok(result, "CryptGetUserKey failed: %08lx\n", GetLastError());
1601 CryptDestroyKey(key);
1603 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1604 CRYPT_DELETEKEYSET);
1609 if (!init_environment())
1621 test_block_cipher_modes();
1622 test_import_private();
1623 test_verify_signature();
1625 test_import_export();
1626 test_enum_container();
1627 clean_up_environment();
1628 test_schannel_provider();
1629 test_null_provider();