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 };
501 static const BYTE rc2_128_encrypted[] = {
502 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
507 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
509 unsigned char pbData[2000], pbHashValue[16];
512 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
515 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
517 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
519 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
520 ok(result, "%08x\n", GetLastError());
523 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
524 ok(result, "%08x\n", GetLastError());
526 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
527 ok(result, "%08x\n", GetLastError());
529 dwLen = sizeof(DWORD);
530 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
531 ok(result, "%08x\n", GetLastError());
533 dwMode = CRYPT_MODE_CBC;
534 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
535 ok(result, "%08x\n", GetLastError());
537 dwLen = sizeof(DWORD);
538 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
539 ok(result, "%08x\n", GetLastError());
541 dwLen = sizeof(DWORD);
542 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
543 ok(result, "%08x\n", GetLastError());
545 dwLen = sizeof(DWORD);
546 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
547 ok(result, "%08x\n", GetLastError());
549 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
550 ok(result, "%08x\n", GetLastError());
551 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
552 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
553 HeapFree(GetProcessHeap(), 0, pbTemp);
555 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
556 ok(result, "%08x\n", GetLastError());
557 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
558 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
559 HeapFree(GetProcessHeap(), 0, pbTemp);
561 dwLen = sizeof(DWORD);
562 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
564 result = CryptDestroyHash(hHash);
565 ok(result, "%08x\n", GetLastError());
568 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
569 ok(result, "%08x\n", GetLastError());
571 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
573 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
574 ok(result, "%08x\n", GetLastError());
575 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
576 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
577 HeapFree(GetProcessHeap(), 0, pbTemp);
579 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
580 ok(result, "%08x\n", GetLastError());
582 result = CryptDestroyKey(hKey);
583 ok(result, "%08x\n", GetLastError());
586 /* Again, but test setting the effective key len */
587 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
589 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
591 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
593 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
594 ok(result, "%08x\n", GetLastError());
597 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
598 ok(result, "%08x\n", GetLastError());
600 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
601 ok(result, "%08x\n", GetLastError());
603 SetLastError(0xdeadbeef);
604 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
605 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
607 SetLastError(0xdeadbeef);
608 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
609 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
611 SetLastError(0xdeadbeef);
612 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
614 dwLen = sizeof(dwKeyLen);
615 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
616 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
617 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
618 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
621 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
622 ok(result, "%d\n", GetLastError());
624 dwLen = sizeof(dwKeyLen);
625 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
626 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
627 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
628 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
630 result = CryptDestroyHash(hHash);
631 ok(result, "%08x\n", GetLastError());
634 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
635 ok(result, "%08x\n", GetLastError());
637 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
638 "RC2 encryption failed!\n");
640 /* Oddly enough this succeeds, though it should have no effect */
642 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
643 ok(result, "%d\n", GetLastError());
645 result = CryptDestroyKey(hKey);
646 ok(result, "%08x\n", GetLastError());
650 static void test_rc4(void)
652 static const BYTE rc4[16] = {
653 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
654 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
658 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
659 unsigned char pbData[2000], *pbTemp;
660 unsigned char pszBuffer[256];
663 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
666 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
668 /* rsaenh compiled without OpenSSL */
669 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
671 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
672 ok(result, "%08x\n", GetLastError());
675 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
676 ok(result, "%08x\n", GetLastError());
678 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
679 ok(result, "%08x\n", GetLastError());
681 dwLen = sizeof(DWORD);
682 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
683 ok(result, "%08x\n", GetLastError());
685 dwLen = sizeof(DWORD);
686 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
687 ok(result, "%08x\n", GetLastError());
689 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
690 ok(result, "%08x\n", GetLastError());
691 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
692 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
693 HeapFree(GetProcessHeap(), 0, pbTemp);
695 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
696 ok(result, "%08x\n", GetLastError());
697 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
698 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
699 HeapFree(GetProcessHeap(), 0, pbTemp);
701 dwLen = sizeof(DWORD);
702 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
704 result = CryptDestroyHash(hHash);
705 ok(result, "%08x\n", GetLastError());
708 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
709 ok(result, "%08x\n", GetLastError());
711 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
712 ok(result, "%08x\n", GetLastError());
714 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
716 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
717 ok(result, "%08x\n", GetLastError());
719 result = CryptDestroyKey(hKey);
720 ok(result, "%08x\n", GetLastError());
724 static void test_hmac(void) {
728 /* Using CALG_MD2 here fails on Windows 2003, why ? */
729 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
732 static const BYTE hmac[16] = {
733 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
734 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
737 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
739 if (!derive_key(CALG_RC2, &hKey, 56)) return;
741 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
742 ok(result, "%08x\n", GetLastError());
745 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
746 ok(result, "%08x\n", GetLastError());
748 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
749 ok(result, "%08x\n", GetLastError());
751 dwLen = sizeof(abData)/sizeof(BYTE);
752 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
753 ok(result, "%08x\n", GetLastError());
755 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
757 result = CryptDestroyHash(hHash);
758 ok(result, "%08x\n", GetLastError());
760 result = CryptDestroyKey(hKey);
761 ok(result, "%08x\n", GetLastError());
764 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
765 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
768 static void test_mac(void) {
773 BYTE abData[256], abEnc[264];
774 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
777 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
778 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
780 if (!derive_key(CALG_RC2, &hKey, 56)) return;
783 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
784 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
786 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
787 ok(result, "%08x\n", GetLastError());
790 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
791 ok(result, "%08x\n", GetLastError());
793 dwLen = sizeof(abData)/sizeof(BYTE);
794 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
795 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
797 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
799 result = CryptDestroyHash(hHash);
800 ok(result, "%08x\n", GetLastError());
802 result = CryptDestroyKey(hKey);
803 ok(result, "%08x\n", GetLastError());
806 if (!derive_key(CALG_RC4, &hKey, 56)) return;
808 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
809 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
811 result = CryptDestroyKey(hKey);
812 ok(result, "%08x\n", GetLastError());
815 static BYTE abPlainPrivateKey[596] = {
816 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
817 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
818 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
819 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
820 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
821 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
822 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
823 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
824 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
825 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
826 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
827 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
828 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
829 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
830 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
831 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
832 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
833 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
834 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
835 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
836 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
837 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
838 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
839 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
840 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
841 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
842 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
843 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
844 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
845 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
846 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
847 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
848 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
849 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
850 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
851 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
852 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
853 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
854 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
855 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
856 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
857 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
858 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
859 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
860 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
861 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
862 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
863 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
864 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
865 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
866 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
867 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
868 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
869 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
870 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
871 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
872 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
873 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
874 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
875 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
876 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
877 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
878 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
879 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
880 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
881 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
882 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
883 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
884 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
885 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
886 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
887 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
888 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
889 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
890 0xf2, 0x5d, 0x58, 0x07
893 static void test_import_private(void)
896 HCRYPTKEY hKeyExchangeKey, hSessionKey;
898 static BYTE abSessionKey[148] = {
899 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
900 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
901 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
902 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
903 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
904 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
905 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
906 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
907 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
908 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
909 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
910 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
911 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
912 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
913 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
914 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
915 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
916 0x04, 0x8c, 0x49, 0x92
918 static BYTE abEncryptedMessage[12] = {
919 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
920 0x1c, 0xfd, 0xde, 0x71
923 dwLen = (DWORD)sizeof(abPlainPrivateKey);
924 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
926 /* rsaenh compiled without OpenSSL */
927 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
931 dwLen = (DWORD)sizeof(abSessionKey);
932 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
933 ok(result, "%08x\n", GetLastError());
936 dwLen = (DWORD)sizeof(abEncryptedMessage);
937 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
938 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
939 "%08x, len: %d\n", GetLastError(), dwLen);
941 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
943 dwLen = (DWORD)sizeof(abSessionKey);
944 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
945 ok(result, "%08x\n", GetLastError());
948 dwLen = (DWORD)sizeof(abSessionKey);
949 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
950 ok(result, "%08x\n", GetLastError());
954 static void test_verify_signature(void) {
956 HCRYPTKEY hPubSignKey;
957 BYTE abData[] = "Wine rocks!";
959 BYTE abPubKey[148] = {
960 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
961 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
962 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
963 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
964 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
965 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
966 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
967 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
968 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
969 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
970 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
971 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
972 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
973 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
974 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
975 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
976 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
977 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
978 0xe1, 0x21, 0x50, 0xac
980 /* md2 with hash oid */
981 BYTE abSignatureMD2[128] = {
982 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
983 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
984 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
985 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
986 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
987 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
988 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
989 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
990 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
991 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
992 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
993 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
994 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
995 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
996 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
997 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
999 /* md2 without hash oid */
1000 BYTE abSignatureMD2NoOID[128] = {
1001 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1002 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1003 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1004 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1005 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1006 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1007 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1008 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1009 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1010 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1011 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1012 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1013 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1014 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1015 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1016 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1018 /* md4 with hash oid */
1019 BYTE abSignatureMD4[128] = {
1020 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1021 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1022 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1023 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1024 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1025 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1026 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1027 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1028 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1029 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1030 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1031 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1032 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1033 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1034 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1035 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1037 /* md4 without hash oid */
1038 BYTE abSignatureMD4NoOID[128] = {
1039 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1040 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1041 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1042 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1043 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1044 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1045 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1046 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1047 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1048 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1049 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1050 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1051 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1052 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1053 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1054 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1056 /* md5 with hash oid */
1057 BYTE abSignatureMD5[128] = {
1058 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1059 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1060 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1061 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1062 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1063 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1064 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1065 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1066 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1067 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1068 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1069 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1070 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1071 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1072 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1073 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1075 /* md5 without hash oid */
1076 BYTE abSignatureMD5NoOID[128] = {
1077 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1078 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1079 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1080 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1081 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1082 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1083 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1084 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1085 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1086 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1087 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1088 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1089 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1090 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1091 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1092 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1094 /* sha with hash oid */
1095 BYTE abSignatureSHA[128] = {
1096 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1097 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1098 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1099 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1100 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1101 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1102 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1103 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1104 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1105 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1106 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1107 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1108 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1109 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1110 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1111 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1113 /* sha without hash oid */
1114 BYTE abSignatureSHANoOID[128] = {
1115 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1116 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1117 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1118 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1119 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1120 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1121 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1122 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1123 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1124 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1125 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1126 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1127 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1128 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1129 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1130 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1133 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1134 ok(result, "%08x\n", GetLastError());
1135 if (!result) return;
1137 result = CryptCreateHash(hProv, CALG_MD2, 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 /*check that a NULL pointer signature is correctly handled*/
1146 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1147 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1148 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1151 /* check that we get a bad signature error when the signature is too short*/
1152 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1153 ok(!result && NTE_BAD_SIGNATURE == GetLastError(),
1154 "Expected NTE_BAD_SIGNATURE error, got %08x\n", GetLastError());
1157 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1158 ok(result, "%08x\n", GetLastError());
1159 if (!result) return;
1161 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1162 ok(result, "%08x\n", GetLastError());
1163 if (!result) return;
1165 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1166 * the OID at all. */
1167 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1168 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1169 if (result) return;*/
1171 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1172 ok(result, "%08x\n", GetLastError());
1173 if (!result) return;
1175 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1176 ok(result, "%08x\n", GetLastError());
1177 if (!result) return;
1179 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1180 ok(result, "%08x\n", GetLastError());
1181 if (!result) return;
1183 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1184 ok(result, "%08x\n", GetLastError());
1185 if (!result) return;
1187 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1188 ok(result, "%08x\n", GetLastError());
1189 if (!result) return;
1191 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1192 ok(result, "%08x\n", GetLastError());
1193 if (!result) return;
1195 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1196 ok(result, "%08x\n", GetLastError());
1197 if (!result) return;
1199 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1200 ok(result, "%08x\n", GetLastError());
1201 if (!result) return;
1203 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1204 ok(result, "%08x\n", GetLastError());
1205 if (!result) return;
1207 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1208 ok(result, "%08x\n", GetLastError());
1209 if (!result) return;
1211 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1212 ok(result, "%08x\n", GetLastError());
1213 if (!result) return;
1215 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1216 ok(result, "%08x\n", GetLastError());
1217 if (!result) return;
1220 static void test_rsa_encrypt(void)
1223 BYTE abData[2048] = "Wine rocks!";
1227 /* It is allowed to use the key exchange key for encryption/decryption */
1228 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1229 ok (result, "%08x\n", GetLastError());
1230 if (!result) return;
1233 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1234 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1235 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1237 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1238 ok (result, "%08x\n", GetLastError());
1239 if (!result) return;
1241 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1242 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1244 CryptDestroyKey(hRSAKey);
1246 /* It is not allowed to use the signature key for encryption/decryption */
1247 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1248 ok (result, "%08x\n", GetLastError());
1249 if (!result) return;
1252 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1253 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1255 CryptDestroyKey(hRSAKey);
1258 static void test_import_export(void)
1260 DWORD dwLen, dwDataLen;
1261 HCRYPTKEY hPublicKey;
1264 BYTE emptyKey[2048];
1265 static BYTE abPlainPublicKey[84] = {
1266 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1267 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1268 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1269 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1270 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1271 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1272 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1273 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1274 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1275 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1276 0x11, 0x11, 0x11, 0x11
1280 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1281 ok(result, "failed to import the public key\n");
1283 dwDataLen=sizeof(algID);
1284 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1285 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1286 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1288 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1289 ok(result, "failed to export the fresh imported public key\n");
1290 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1291 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1294 static void test_schannel_provider(void)
1297 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1298 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1301 SCHANNEL_ALG saSChannelAlg;
1302 CRYPT_DATA_BLOB data_blob;
1303 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1304 BYTE abPlainPrivateKey[596] = {
1305 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1306 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1307 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1308 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1309 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1310 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1311 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1312 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1313 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1314 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1315 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1316 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1317 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1318 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1319 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1320 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1321 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1322 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1323 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1324 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1325 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1326 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1327 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1328 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1329 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1330 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1331 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1332 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1333 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1334 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1335 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1336 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1337 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1338 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1339 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1340 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1341 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1342 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1343 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1344 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1345 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1346 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1347 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1348 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1349 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1350 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1351 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1352 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1353 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1354 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1355 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1356 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1357 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1358 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1359 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1360 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1361 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1362 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1363 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1364 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1365 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1366 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1367 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1368 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1369 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1370 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1371 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1372 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1373 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1374 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1375 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1376 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1377 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1378 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1379 0xf2, 0x5d, 0x58, 0x07
1381 BYTE abTLS1Master[140] = {
1382 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1383 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1384 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1385 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1386 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1387 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1388 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1389 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1390 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1391 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1392 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1393 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1394 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1395 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1396 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1397 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1398 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1399 0xd3, 0x1e, 0x82, 0xb3
1401 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1402 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1403 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1404 BYTE abClientFinished[16] = "client finished";
1405 BYTE abData[16] = "Wine rocks!";
1407 static const BYTE abEncryptedData[16] = {
1408 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1409 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1411 static const BYTE abPRF[16] = {
1412 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1413 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1415 static const BYTE abMD5[16] = {
1416 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1417 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1420 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1421 ok (result, "%08x\n", GetLastError());
1423 CryptReleaseContext(hProv, 0);
1425 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1426 ok (result, "%08x\n", GetLastError());
1427 if (!result) return;
1429 /* To get deterministic results, we import the TLS1 master secret (which
1430 * is typically generated from a random generator). Therefore, we need
1432 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1433 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1434 ok (result, "%08x\n", GetLastError());
1435 if (!result) return;
1437 dwLen = (DWORD)sizeof(abTLS1Master);
1438 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1439 ok (result, "%08x\n", GetLastError());
1440 if (!result) return;
1442 /* Setting the TLS1 client and server random parameters, as well as the
1443 * MAC and encryption algorithm parameters. */
1444 data_blob.cbData = 33;
1445 data_blob.pbData = abClientSecret;
1446 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1447 ok (result, "%08x\n", GetLastError());
1448 if (!result) return;
1450 data_blob.cbData = 33;
1451 data_blob.pbData = abServerSecret;
1452 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1453 ok (result, "%08x\n", GetLastError());
1454 if (!result) return;
1456 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1457 saSChannelAlg.Algid = CALG_DES;
1458 saSChannelAlg.cBits = 64;
1459 saSChannelAlg.dwFlags = 0;
1460 saSChannelAlg.dwReserved = 0;
1461 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1462 ok (result, "%08x\n", GetLastError());
1463 if (!result) return;
1465 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1466 saSChannelAlg.Algid = CALG_MD5;
1467 saSChannelAlg.cBits = 128;
1468 saSChannelAlg.dwFlags = 0;
1469 saSChannelAlg.dwReserved = 0;
1470 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1471 ok (result, "%08x\n", GetLastError());
1472 if (!result) return;
1474 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1475 * (Keys can only be derived from hashes, not from other keys.) */
1476 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1477 ok (result, "%08x\n", GetLastError());
1478 if (!result) return;
1480 /* Deriving the server write encryption key from the master hash */
1481 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1482 ok (result, "%08x\n", GetLastError());
1483 if (!result) return;
1485 /* Encrypting some data with the server write encryption key and checking the result. */
1487 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1488 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1490 /* Second test case: Test the TLS1 pseudo random number function. */
1491 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1492 ok (result, "%08x\n", GetLastError());
1493 if (!result) return;
1495 /* Set the label and seed parameters for the random number function */
1496 data_blob.cbData = 36;
1497 data_blob.pbData = abHashedHandshakes;
1498 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1499 ok (result, "%08x\n", GetLastError());
1500 if (!result) return;
1502 data_blob.cbData = 15;
1503 data_blob.pbData = abClientFinished;
1504 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1505 ok (result, "%08x\n", GetLastError());
1506 if (!result) return;
1508 /* Generate some pseudo random bytes and check if they are correct. */
1509 dwLen = (DWORD)sizeof(abData);
1510 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1511 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1512 "%08x\n", GetLastError());
1514 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1515 * Hash some data with the HMAC. Compare results. */
1516 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1517 ok (result, "%08x\n", GetLastError());
1518 if (!result) return;
1520 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1521 ok (result, "%08x\n", GetLastError());
1522 if (!result) return;
1524 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1525 ok (result, "%08x\n", GetLastError());
1526 if (!result) return;
1528 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1529 ok (result, "%08x\n", GetLastError());
1530 if (!result) return;
1532 dwLen = (DWORD)sizeof(abMD5Hash);
1533 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1534 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1536 CryptDestroyHash(hHMAC);
1537 CryptDestroyHash(hTLS1PRF);
1538 CryptDestroyHash(hMasterHash);
1539 CryptDestroyKey(hServerWriteMACKey);
1540 CryptDestroyKey(hServerWriteKey);
1541 CryptDestroyKey(hRSAKey);
1542 CryptDestroyKey(hMasterSecret);
1543 CryptReleaseContext(hProv, 0);
1544 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1547 static void test_enum_container(void)
1549 BYTE abContainerName[256];
1551 BOOL result, fFound = FALSE;
1553 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1554 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1555 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1556 ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1558 /* If the result fits into abContainerName dwBufferLen is left untouched */
1559 dwBufferLen = (DWORD)sizeof(abContainerName);
1560 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1561 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1563 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1565 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1566 dwBufferLen = (DWORD)sizeof(abContainerName);
1567 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1569 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1572 static BYTE signBlob[] = {
1573 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1574 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1575 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1576 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1577 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1578 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1579 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1580 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1581 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1582 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1583 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1584 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1585 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1586 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1587 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1588 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1589 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1590 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1591 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1592 0xb6,0x85,0x86,0x07 };
1594 static void test_null_provider(void)
1599 DWORD keySpec, dataLen,dwParam;
1600 char szName[MAX_PATH];
1602 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1603 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1604 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1605 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1606 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1607 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1608 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1609 CRYPT_DELETEKEYSET);
1610 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1611 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1612 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1613 CRYPT_DELETEKEYSET);
1614 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1615 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1616 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1617 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1618 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1620 /* Delete the default container. */
1621 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1622 /* Once you've deleted the default container you can't open it as if it
1625 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1626 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1627 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1628 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1629 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1630 CRYPT_VERIFYCONTEXT);
1631 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1632 if (!result) return;
1633 dataLen = sizeof(keySpec);
1634 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1636 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1637 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1638 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1639 * supported, you can't get the keys from this container.
1641 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1642 ok(!result && GetLastError() == NTE_NO_KEY,
1643 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1644 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1645 ok(!result && GetLastError() == NTE_NO_KEY,
1646 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1647 result = CryptReleaseContext(prov, 0);
1648 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1649 /* You can create a new default container. */
1650 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1652 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1653 /* But you still can't get the keys (until one's been generated.) */
1654 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1655 ok(!result && GetLastError() == NTE_NO_KEY,
1656 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1657 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1658 ok(!result && GetLastError() == NTE_NO_KEY,
1659 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1660 CryptReleaseContext(prov, 0);
1661 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1663 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1664 CRYPT_DELETEKEYSET);
1665 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1666 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1667 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1668 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1669 CRYPT_VERIFYCONTEXT);
1670 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1671 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1672 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1674 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1675 if (!result) return;
1676 /* Test provider parameters getter */
1677 dataLen = sizeof(dwParam);
1678 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1679 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1680 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1681 dataLen = sizeof(dwParam);
1682 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1683 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1684 "Expected 0, got 0x%08X\n",dwParam);
1685 dataLen = sizeof(dwParam);
1686 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1687 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1688 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1689 dataLen = sizeof(keySpec);
1690 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1691 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1692 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1693 /* PP_CONTAINER parameter */
1694 dataLen = sizeof(szName);
1695 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1696 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1697 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1698 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1699 /* PP_UNIQUE_CONTAINER parameter */
1700 dataLen = sizeof(szName);
1701 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1702 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1703 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1704 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1705 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1706 ok(!result && GetLastError() == NTE_NO_KEY,
1707 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1708 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1709 ok(!result && GetLastError() == NTE_NO_KEY,
1710 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1712 /* Importing a key exchange blob.. */
1713 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1715 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1716 CryptDestroyKey(key);
1717 /* allows access to the key exchange key.. */
1718 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1719 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1720 CryptDestroyKey(key);
1721 /* but not to the private key. */
1722 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1723 ok(!result && GetLastError() == NTE_NO_KEY,
1724 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1725 CryptReleaseContext(prov, 0);
1726 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1727 CRYPT_DELETEKEYSET);
1729 /* Whereas importing a sign blob.. */
1730 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1732 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1733 if (!result) return;
1734 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1735 ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1736 /* doesn't allow access to the key exchange key.. */
1737 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1738 ok(!result && GetLastError() == NTE_NO_KEY,
1739 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1740 /* but does to the private key. */
1741 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1742 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1743 CryptDestroyKey(key);
1745 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1746 CRYPT_DELETEKEYSET);
1749 /* test for the bug in accessing the user key in a container
1751 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1753 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1754 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1755 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1756 CryptDestroyKey(key);
1757 CryptReleaseContext(prov,0);
1758 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1759 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1760 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1761 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1762 CryptDestroyKey(key);
1764 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1765 CRYPT_DELETEKEYSET);
1767 /* test the machine key set */
1768 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1769 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1770 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1771 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1772 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1773 CryptReleaseContext(prov, 0);
1774 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1775 CRYPT_MACHINE_KEYSET);
1776 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1777 CryptReleaseContext(prov,0);
1778 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1779 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1780 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1782 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1783 CRYPT_MACHINE_KEYSET);
1784 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1785 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1791 if (!init_environment())
1803 test_block_cipher_modes();
1804 test_import_private();
1805 test_verify_signature();
1807 test_import_export();
1808 test_enum_container();
1809 clean_up_environment();
1810 test_schannel_provider();
1811 test_null_provider();