rsaenh: Fix crash in RSAENH_CPVerifySignature if pbSignature is set to NULL or if...
[wine/hacks.git] / dlls / rsaenh / tests / rsaenh.c
blob5d17be2f6856146139c02a8ab3c68a514c50c198
1 /*
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
21 #include <string.h>
22 #include <stdio.h>
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "wincrypt.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) {
38 char szTemp[256];
39 DWORD i, j;
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]);
45 trace(szTemp);
47 for (j=0; i<dwLen; j++,i++) {
48 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
50 trace(szTemp);
54 static int init_environment(void)
56 HCRYPTKEY hKey;
57 BOOL result;
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,
71 CRYPT_NEWKEYSET);
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);
81 return 1;
84 static void clean_up_environment(void)
86 BOOL result;
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)
96 BOOL result;
97 DWORD dwLen, dwInc;
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)
110 BOOL result;
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 */
119 return;
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)
132 HCRYPTHASH hHash;
133 BOOL result;
134 unsigned char pbData[2000];
135 int i;
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);
140 if (!result) {
141 /* rsaenh compiled without OpenSSL */
142 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
143 return FALSE;
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;
153 len = 2000;
154 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
155 ok(result, "%08x\n", GetLastError());
156 CryptDestroyHash(hHash);
157 return TRUE;
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];
175 BOOL result;
176 HCRYPTHASH hHash, hHashClone;
177 BYTE pbHashValue[36];
178 DWORD hashlen, len;
179 int i;
181 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
183 /* MD2 Hashing */
184 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
185 if (!result) {
186 /* rsaenh compiled without OpenSSL */
187 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
188 } else {
189 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
190 ok(result, "%08x\n", GetLastError());
192 len = sizeof(DWORD);
193 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
194 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
196 len = 16;
197 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
198 ok(result, "%08x\n", GetLastError());
200 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
202 result = CryptDestroyHash(hHash);
203 ok(result, "%08x\n", GetLastError());
206 /* MD4 Hashing */
207 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
208 ok(result, "%08x\n", GetLastError());
210 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
211 ok(result, "%08x\n", GetLastError());
213 len = sizeof(DWORD);
214 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
215 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
217 len = 16;
218 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
219 ok(result, "%08x\n", GetLastError());
221 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
223 result = CryptDestroyHash(hHash);
224 ok(result, "%08x\n", GetLastError());
226 /* MD5 Hashing */
227 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
228 ok(result, "%08x\n", GetLastError());
230 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
231 ok(result, "%08x\n", GetLastError());
233 len = sizeof(DWORD);
234 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
235 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
237 len = 16;
238 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
239 ok(result, "%08x\n", GetLastError());
241 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
243 result = CryptDestroyHash(hHash);
244 ok(result, "%08x\n", GetLastError());
246 /* SHA1 Hashing */
247 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
248 ok(result, "%08x\n", GetLastError());
250 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
251 ok(result, "%08x\n", GetLastError());
253 if(pCryptDuplicateHash) {
254 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
255 ok(result, "%08x\n", GetLastError());
257 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
258 ok(result, "%08x\n", GetLastError());
260 len = sizeof(DWORD);
261 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
262 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
264 len = 20;
265 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
266 ok(result, "%08x\n", GetLastError());
268 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
270 result = CryptDestroyHash(hHashClone);
271 ok(result, "%08x\n", GetLastError());
274 result = CryptDestroyHash(hHash);
275 ok(result, "%08x\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 };
292 HCRYPTKEY hKey;
293 BOOL result;
294 BYTE abData[24];
295 DWORD dwMode, dwLen;
297 result = derive_key(CALG_RC2, &hKey, 40);
298 if (!result) return;
300 memcpy(abData, plain, sizeof(abData));
302 dwMode = CRYPT_MODE_ECB;
303 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
304 ok(result, "%08x\n", GetLastError());
306 dwLen = 23;
307 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
308 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
309 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
311 SetLastError(ERROR_SUCCESS);
312 dwLen = 23;
313 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
314 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
315 "%08x, dwLen: %d\n", GetLastError(), dwLen);
317 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
318 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
319 "%08x, dwLen: %d\n", GetLastError(), dwLen);
321 dwMode = CRYPT_MODE_CBC;
322 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
323 ok(result, "%08x\n", GetLastError());
325 dwLen = 23;
326 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
327 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
328 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
330 dwLen = 23;
331 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
332 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
333 "%08x, dwLen: %d\n", GetLastError(), dwLen);
335 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
336 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
337 "%08x, dwLen: %d\n", GetLastError(), dwLen);
339 dwMode = CRYPT_MODE_CFB;
340 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
341 ok(result, "%08x\n", GetLastError());
343 dwLen = 16;
344 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
345 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
347 dwLen = 7;
348 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
349 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
350 "%08x, dwLen: %d\n", GetLastError(), dwLen);
352 dwLen = 8;
353 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
354 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
356 dwLen = 16;
357 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
358 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
359 "%08x, dwLen: %d\n", GetLastError(), dwLen);
361 dwMode = CRYPT_MODE_OFB;
362 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
363 ok(result, "%08x\n", GetLastError());
365 dwLen = 23;
366 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
367 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
370 static void test_3des112(void)
372 HCRYPTKEY hKey;
373 BOOL result;
374 DWORD dwLen;
375 unsigned char pbData[16];
376 int i;
378 result = derive_key(CALG_3DES_112, &hKey, 0);
379 if (!result) {
380 /* rsaenh compiled without OpenSSL */
381 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
382 return;
385 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
387 dwLen = 13;
388 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
389 ok(result, "%08x\n", GetLastError());
391 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
392 ok(result, "%08x\n", GetLastError());
394 result = CryptDestroyKey(hKey);
395 ok(result, "%08x\n", GetLastError());
398 static void test_des(void)
400 HCRYPTKEY hKey;
401 BOOL result;
402 DWORD dwLen, dwMode;
403 unsigned char pbData[16];
404 int i;
406 result = derive_key(CALG_DES, &hKey, 56);
407 if (!result) {
408 /* rsaenh compiled without OpenSSL */
409 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
410 return;
413 dwMode = CRYPT_MODE_ECB;
414 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
415 ok(result, "%08x\n", GetLastError());
417 dwLen = sizeof(DWORD);
418 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
419 ok(result, "%08x\n", GetLastError());
421 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
423 dwLen = 13;
424 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
425 ok(result, "%08x\n", GetLastError());
427 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
428 ok(result, "%08x\n", GetLastError());
430 result = CryptDestroyKey(hKey);
431 ok(result, "%08x\n", GetLastError());
434 static void test_3des(void)
436 HCRYPTKEY hKey;
437 BOOL result;
438 DWORD dwLen;
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 };
443 int i;
445 result = derive_key(CALG_3DES, &hKey, 0);
446 if (!result) return;
448 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
450 dwLen = 13;
451 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
452 ok(result, "%08x\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, "%08x\n", GetLastError());
459 result = CryptDestroyKey(hKey);
460 ok(result, "%08x\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 };
468 HCRYPTHASH hHash;
469 HCRYPTKEY hKey;
470 BOOL result;
471 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
472 BYTE *pbTemp;
473 unsigned char pbData[2000], pbHashValue[16];
474 int i;
476 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
478 /* MD2 Hashing */
479 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
480 if (!result) {
481 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
482 } else {
483 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
484 ok(result, "%08x\n", GetLastError());
486 dwLen = 16;
487 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
488 ok(result, "%08x\n", GetLastError());
490 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
491 ok(result, "%08x\n", GetLastError());
493 dwLen = sizeof(DWORD);
494 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
495 ok(result, "%08x\n", GetLastError());
497 dwMode = CRYPT_MODE_CBC;
498 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
499 ok(result, "%08x\n", GetLastError());
501 dwLen = sizeof(DWORD);
502 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
503 ok(result, "%08x\n", GetLastError());
505 dwLen = sizeof(DWORD);
506 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
507 ok(result, "%08x\n", GetLastError());
509 dwLen = sizeof(DWORD);
510 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
511 ok(result, "%08x\n", GetLastError());
513 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
514 ok(result, "%08x\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, "%08x\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, "%08x\n", GetLastError());
531 dwDataLen = 13;
532 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
533 ok(result, "%08x\n", GetLastError());
535 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
537 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
538 ok(result, "%08x\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, "%08x\n", GetLastError());
546 result = CryptDestroyKey(hKey);
547 ok(result, "%08x\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 };
556 BOOL result;
557 HCRYPTHASH hHash;
558 HCRYPTKEY hKey;
559 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
560 unsigned char pbData[2000], *pbTemp;
561 unsigned char pszBuffer[256];
562 int i;
564 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
566 /* MD2 Hashing */
567 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
568 if (!result) {
569 /* rsaenh compiled without OpenSSL */
570 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
571 } else {
572 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
573 ok(result, "%08x\n", GetLastError());
575 dwLen = 16;
576 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
577 ok(result, "%08x\n", GetLastError());
579 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
580 ok(result, "%08x\n", GetLastError());
582 dwLen = sizeof(DWORD);
583 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
584 ok(result, "%08x\n", GetLastError());
586 dwLen = sizeof(DWORD);
587 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
588 ok(result, "%08x\n", GetLastError());
590 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
591 ok(result, "%08x\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, "%08x\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, "%08x\n", GetLastError());
608 dwDataLen = 16;
609 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
610 ok(result, "%08x\n", GetLastError());
611 dwDataLen = 16;
612 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
613 ok(result, "%08x\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, "%08x\n", GetLastError());
620 result = CryptDestroyKey(hKey);
621 ok(result, "%08x\n", GetLastError());
625 static void test_hmac(void) {
626 HCRYPTKEY hKey;
627 HCRYPTHASH hHash;
628 BOOL result;
629 /* Using CALG_MD2 here fails on Windows 2003, why ? */
630 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
631 DWORD dwLen;
632 BYTE abData[256];
633 static const BYTE hmac[16] = {
634 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
635 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
636 int i;
638 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
640 if (!derive_key(CALG_RC2, &hKey, 56)) return;
642 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
643 ok(result, "%08x\n", GetLastError());
644 if (!result) return;
646 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
647 ok(result, "%08x\n", GetLastError());
649 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
650 ok(result, "%08x\n", GetLastError());
652 dwLen = sizeof(abData)/sizeof(BYTE);
653 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
654 ok(result, "%08x\n", GetLastError());
656 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
658 result = CryptDestroyHash(hHash);
659 ok(result, "%08x\n", GetLastError());
661 result = CryptDestroyKey(hKey);
662 ok(result, "%08x\n", GetLastError());
664 /* Provoke errors */
665 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
666 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
669 static void test_mac(void) {
670 HCRYPTKEY hKey;
671 HCRYPTHASH hHash;
672 BOOL result;
673 DWORD dwLen;
674 BYTE abData[256], abEnc[264];
675 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
676 int i;
678 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
679 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
681 if (!derive_key(CALG_RC2, &hKey, 56)) return;
683 dwLen = 256;
684 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
685 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
687 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
688 ok(result, "%08x\n", GetLastError());
689 if (!result) return;
691 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
692 ok(result, "%08x\n", GetLastError());
694 dwLen = sizeof(abData)/sizeof(BYTE);
695 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
696 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
698 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
700 result = CryptDestroyHash(hHash);
701 ok(result, "%08x\n", GetLastError());
703 result = CryptDestroyKey(hKey);
704 ok(result, "%08x\n", GetLastError());
706 /* Provoke errors */
707 if (!derive_key(CALG_RC4, &hKey, 56)) return;
709 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
710 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
712 result = CryptDestroyKey(hKey);
713 ok(result, "%08x\n", GetLastError());
716 static BYTE abPlainPrivateKey[596] = {
717 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
718 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
719 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
720 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
721 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
722 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
723 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
724 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
725 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
726 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
727 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
728 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
729 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
730 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
731 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
732 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
733 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
734 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
735 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
736 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
737 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
738 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
739 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
740 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
741 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
742 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
743 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
744 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
745 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
746 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
747 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
748 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
749 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
750 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
751 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
752 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
753 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
754 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
755 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
756 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
757 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
758 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
759 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
760 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
761 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
762 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
763 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
764 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
765 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
766 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
767 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
768 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
769 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
770 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
771 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
772 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
773 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
774 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
775 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
776 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
777 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
778 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
779 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
780 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
781 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
782 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
783 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
784 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
785 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
786 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
787 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
788 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
789 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
790 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
791 0xf2, 0x5d, 0x58, 0x07
794 static void test_import_private(void)
796 DWORD dwLen;
797 HCRYPTKEY hKeyExchangeKey, hSessionKey;
798 BOOL result;
799 static BYTE abSessionKey[148] = {
800 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
801 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
802 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
803 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
804 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
805 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
806 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
807 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
808 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
809 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
810 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
811 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
812 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
813 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
814 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
815 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
816 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
817 0x04, 0x8c, 0x49, 0x92
819 static BYTE abEncryptedMessage[12] = {
820 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
821 0x1c, 0xfd, 0xde, 0x71
824 dwLen = (DWORD)sizeof(abPlainPrivateKey);
825 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
826 if (!result) {
827 /* rsaenh compiled without OpenSSL */
828 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
829 return;
832 dwLen = (DWORD)sizeof(abSessionKey);
833 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
834 ok(result, "%08x\n", GetLastError());
835 if (!result) return;
837 dwLen = (DWORD)sizeof(abEncryptedMessage);
838 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
839 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
840 "%08x, len: %d\n", GetLastError(), dwLen);
842 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
844 dwLen = (DWORD)sizeof(abSessionKey);
845 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
846 ok(result, "%08x\n", GetLastError());
847 if (!result) return;
849 dwLen = (DWORD)sizeof(abSessionKey);
850 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
851 ok(result, "%08x\n", GetLastError());
852 if (!result) return;
855 static void test_verify_signature(void) {
856 HCRYPTHASH hHash;
857 HCRYPTKEY hPubSignKey;
858 BYTE abData[] = "Wine rocks!";
859 BOOL result;
860 BYTE abPubKey[148] = {
861 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
862 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
863 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
864 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
865 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
866 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
867 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
868 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
869 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
870 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
871 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
872 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
873 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
874 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
875 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
876 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
877 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
878 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
879 0xe1, 0x21, 0x50, 0xac
881 /* md2 with hash oid */
882 BYTE abSignatureMD2[128] = {
883 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
884 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
885 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
886 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
887 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
888 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
889 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
890 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
891 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
892 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
893 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
894 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
895 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
896 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
897 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
898 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
900 /* md2 without hash oid */
901 BYTE abSignatureMD2NoOID[128] = {
902 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
903 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
904 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
905 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
906 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
907 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
908 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
909 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
910 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
911 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
912 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
913 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
914 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
915 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
916 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
917 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
919 /* md4 with hash oid */
920 BYTE abSignatureMD4[128] = {
921 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
922 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
923 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
924 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
925 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
926 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
927 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
928 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
929 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
930 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
931 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
932 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
933 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
934 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
935 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
936 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
938 /* md4 without hash oid */
939 BYTE abSignatureMD4NoOID[128] = {
940 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
941 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
942 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
943 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
944 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
945 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
946 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
947 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
948 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
949 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
950 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
951 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
952 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
953 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
954 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
955 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
957 /* md5 with hash oid */
958 BYTE abSignatureMD5[128] = {
959 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
960 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
961 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
962 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
963 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
964 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
965 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
966 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
967 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
968 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
969 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
970 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
971 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
972 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
973 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
974 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
976 /* md5 without hash oid */
977 BYTE abSignatureMD5NoOID[128] = {
978 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
979 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
980 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
981 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
982 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
983 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
984 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
985 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
986 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
987 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
988 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
989 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
990 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
991 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
992 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
993 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
995 /* sha with hash oid */
996 BYTE abSignatureSHA[128] = {
997 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
998 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
999 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1000 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1001 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1002 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1003 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1004 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1005 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1006 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1007 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1008 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1009 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1010 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1011 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1012 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1014 /* sha without hash oid */
1015 BYTE abSignatureSHANoOID[128] = {
1016 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1017 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1018 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1019 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1020 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1021 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1022 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1023 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1024 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1025 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1026 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1027 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1028 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1029 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1030 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1031 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1034 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1035 ok(result, "%08x\n", GetLastError());
1036 if (!result) return;
1038 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1039 ok(result, "%08x\n", GetLastError());
1040 if (!result) return;
1042 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1043 ok(result, "%08x\n", GetLastError());
1044 if (!result) return;
1046 /*check that a NULL pointer signature is correctly handled*/
1047 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1048 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1049 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1050 if (result) return;
1052 /* check that we get a bad signature error when the signature is too short*/
1053 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1054 ok(!result && NTE_BAD_SIGNATURE == GetLastError(),
1055 "Expected NTE_BAD_SIGNATURE error, got %08x\n", GetLastError());
1056 if (result) return;
1058 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1059 ok(result, "%08x\n", GetLastError());
1060 if (!result) return;
1062 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1063 ok(result, "%08x\n", GetLastError());
1064 if (!result) return;
1066 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1067 * the OID at all. */
1068 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1069 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1070 if (result) return;*/
1072 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1073 ok(result, "%08x\n", GetLastError());
1074 if (!result) return;
1076 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1077 ok(result, "%08x\n", GetLastError());
1078 if (!result) return;
1080 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1081 ok(result, "%08x\n", GetLastError());
1082 if (!result) return;
1084 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1085 ok(result, "%08x\n", GetLastError());
1086 if (!result) return;
1088 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1089 ok(result, "%08x\n", GetLastError());
1090 if (!result) return;
1092 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1093 ok(result, "%08x\n", GetLastError());
1094 if (!result) return;
1096 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1097 ok(result, "%08x\n", GetLastError());
1098 if (!result) return;
1100 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1101 ok(result, "%08x\n", GetLastError());
1102 if (!result) return;
1104 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1105 ok(result, "%08x\n", GetLastError());
1106 if (!result) return;
1108 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1109 ok(result, "%08x\n", GetLastError());
1110 if (!result) return;
1112 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1113 ok(result, "%08x\n", GetLastError());
1114 if (!result) return;
1116 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1117 ok(result, "%08x\n", GetLastError());
1118 if (!result) return;
1121 static void test_rsa_encrypt(void)
1123 HCRYPTKEY hRSAKey;
1124 BYTE abData[2048] = "Wine rocks!";
1125 BOOL result;
1126 DWORD dwLen;
1128 /* It is allowed to use the key exchange key for encryption/decryption */
1129 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1130 ok (result, "%08x\n", GetLastError());
1131 if (!result) return;
1133 dwLen = 12;
1134 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1135 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1136 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1137 dwLen = 12;
1138 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1139 ok (result, "%08x\n", GetLastError());
1140 if (!result) return;
1142 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1143 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1145 CryptDestroyKey(hRSAKey);
1147 /* It is not allowed to use the signature key for encryption/decryption */
1148 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1149 ok (result, "%08x\n", GetLastError());
1150 if (!result) return;
1152 dwLen = 12;
1153 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1154 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1156 CryptDestroyKey(hRSAKey);
1159 static void test_import_export(void)
1161 DWORD dwLen, dwDataLen;
1162 HCRYPTKEY hPublicKey;
1163 BOOL result;
1164 ALG_ID algID;
1165 BYTE emptyKey[2048];
1166 static BYTE abPlainPublicKey[84] = {
1167 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1168 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1169 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1170 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1171 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1172 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1173 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1174 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1175 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1176 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1177 0x11, 0x11, 0x11, 0x11
1180 dwLen=84;
1181 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1182 ok(result, "failed to import the public key\n");
1184 dwDataLen=sizeof(algID);
1185 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1186 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1187 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1189 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1190 ok(result, "failed to export the fresh imported public key\n");
1191 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1192 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1195 static void test_schannel_provider(void)
1197 HCRYPTPROV hProv;
1198 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1199 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1200 BOOL result;
1201 DWORD dwLen;
1202 SCHANNEL_ALG saSChannelAlg;
1203 CRYPT_DATA_BLOB data_blob;
1204 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1205 BYTE abPlainPrivateKey[596] = {
1206 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1207 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1208 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1209 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1210 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1211 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1212 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1213 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1214 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1215 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1216 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1217 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1218 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1219 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1220 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1221 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1222 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1223 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1224 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1225 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1226 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1227 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1228 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1229 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1230 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1231 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1232 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1233 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1234 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1235 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1236 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1237 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1238 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1239 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1240 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1241 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1242 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1243 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1244 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1245 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1246 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1247 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1248 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1249 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1250 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1251 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1252 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1253 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1254 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1255 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1256 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1257 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1258 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1259 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1260 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1261 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1262 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1263 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1264 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1265 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1266 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1267 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1268 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1269 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1270 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1271 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1272 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1273 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1274 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1275 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1276 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1277 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1278 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1279 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1280 0xf2, 0x5d, 0x58, 0x07
1282 BYTE abTLS1Master[140] = {
1283 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1284 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1285 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1286 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1287 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1288 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1289 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1290 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1291 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1292 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1293 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1294 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1295 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1296 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1297 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1298 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1299 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1300 0xd3, 0x1e, 0x82, 0xb3
1302 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1303 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1304 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1305 BYTE abClientFinished[16] = "client finished";
1306 BYTE abData[16] = "Wine rocks!";
1307 BYTE abMD5Hash[16];
1308 static const BYTE abEncryptedData[16] = {
1309 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1310 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1312 static const BYTE abPRF[16] = {
1313 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1314 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1316 static const BYTE abMD5[16] = {
1317 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1318 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1321 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1322 ok (result, "%08x\n", GetLastError());
1323 if (!result) return;
1325 /* To get deterministic results, we import the TLS1 master secret (which
1326 * is typically generated from a random generator). Therefore, we need
1327 * an RSA key. */
1328 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1329 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1330 ok (result, "%08x\n", GetLastError());
1331 if (!result) return;
1333 dwLen = (DWORD)sizeof(abTLS1Master);
1334 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1335 ok (result, "%08x\n", GetLastError());
1336 if (!result) return;
1338 /* Setting the TLS1 client and server random parameters, as well as the
1339 * MAC and encryption algorithm parameters. */
1340 data_blob.cbData = 33;
1341 data_blob.pbData = abClientSecret;
1342 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1343 ok (result, "%08x\n", GetLastError());
1344 if (!result) return;
1346 data_blob.cbData = 33;
1347 data_blob.pbData = abServerSecret;
1348 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1349 ok (result, "%08x\n", GetLastError());
1350 if (!result) return;
1352 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1353 saSChannelAlg.Algid = CALG_DES;
1354 saSChannelAlg.cBits = 64;
1355 saSChannelAlg.dwFlags = 0;
1356 saSChannelAlg.dwReserved = 0;
1357 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1358 ok (result, "%08x\n", GetLastError());
1359 if (!result) return;
1361 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1362 saSChannelAlg.Algid = CALG_MD5;
1363 saSChannelAlg.cBits = 128;
1364 saSChannelAlg.dwFlags = 0;
1365 saSChannelAlg.dwReserved = 0;
1366 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1367 ok (result, "%08x\n", GetLastError());
1368 if (!result) return;
1370 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1371 * (Keys can only be derived from hashes, not from other keys.) */
1372 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1373 ok (result, "%08x\n", GetLastError());
1374 if (!result) return;
1376 /* Deriving the server write encryption key from the master hash */
1377 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1378 ok (result, "%08x\n", GetLastError());
1379 if (!result) return;
1381 /* Encrypting some data with the server write encryption key and checking the result. */
1382 dwLen = 12;
1383 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1384 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1386 /* Second test case: Test the TLS1 pseudo random number function. */
1387 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1388 ok (result, "%08x\n", GetLastError());
1389 if (!result) return;
1391 /* Set the label and seed parameters for the random number function */
1392 data_blob.cbData = 36;
1393 data_blob.pbData = abHashedHandshakes;
1394 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1395 ok (result, "%08x\n", GetLastError());
1396 if (!result) return;
1398 data_blob.cbData = 15;
1399 data_blob.pbData = abClientFinished;
1400 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1401 ok (result, "%08x\n", GetLastError());
1402 if (!result) return;
1404 /* Generate some pseudo random bytes and check if they are correct. */
1405 dwLen = (DWORD)sizeof(abData);
1406 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1407 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1408 "%08x\n", GetLastError());
1410 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1411 * Hash some data with the HMAC. Compare results. */
1412 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1413 ok (result, "%08x\n", GetLastError());
1414 if (!result) return;
1416 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1417 ok (result, "%08x\n", GetLastError());
1418 if (!result) return;
1420 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1421 ok (result, "%08x\n", GetLastError());
1422 if (!result) return;
1424 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1425 ok (result, "%08x\n", GetLastError());
1426 if (!result) return;
1428 dwLen = (DWORD)sizeof(abMD5Hash);
1429 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1430 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1432 CryptDestroyHash(hHMAC);
1433 CryptDestroyHash(hTLS1PRF);
1434 CryptDestroyHash(hMasterHash);
1435 CryptDestroyKey(hServerWriteMACKey);
1436 CryptDestroyKey(hServerWriteKey);
1437 CryptDestroyKey(hRSAKey);
1438 CryptDestroyKey(hMasterSecret);
1439 CryptReleaseContext(hProv, 0);
1440 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1443 static void test_enum_container(void)
1445 BYTE abContainerName[256];
1446 DWORD dwBufferLen;
1447 BOOL result, fFound = FALSE;
1449 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1450 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1451 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1452 ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1454 /* If the result fits into abContainerName dwBufferLen is left untouched */
1455 dwBufferLen = (DWORD)sizeof(abContainerName);
1456 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1457 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1459 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1460 do {
1461 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1462 dwBufferLen = (DWORD)sizeof(abContainerName);
1463 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1465 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1468 static BYTE signBlob[] = {
1469 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1470 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1471 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1472 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1473 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1474 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1475 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1476 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1477 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1478 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1479 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1480 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1481 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1482 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1483 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1484 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1485 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1486 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1487 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1488 0xb6,0x85,0x86,0x07 };
1490 static void test_null_provider(void)
1492 HCRYPTPROV prov;
1493 HCRYPTKEY key;
1494 BOOL result;
1495 DWORD keySpec, dataLen,dwParam;
1496 char szName[MAX_PATH];
1498 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1499 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1500 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1501 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1502 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1503 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1504 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1505 CRYPT_DELETEKEYSET);
1506 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1507 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1508 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1509 CRYPT_DELETEKEYSET);
1510 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1511 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1512 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1513 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1514 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1516 /* Delete the default container. */
1517 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1518 /* Once you've deleted the default container you can't open it as if it
1519 * already exists.
1521 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1522 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1523 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1524 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1525 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1526 CRYPT_VERIFYCONTEXT);
1527 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1528 if (!result) return;
1529 dataLen = sizeof(keySpec);
1530 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1531 if (result)
1532 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1533 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1534 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1535 * supported, you can't get the keys from this container.
1537 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1538 ok(!result && GetLastError() == NTE_NO_KEY,
1539 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1540 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1541 ok(!result && GetLastError() == NTE_NO_KEY,
1542 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1543 result = CryptReleaseContext(prov, 0);
1544 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1545 /* You can create a new default container. */
1546 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1547 CRYPT_NEWKEYSET);
1548 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1549 /* But you still can't get the keys (until one's been generated.) */
1550 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1551 ok(!result && GetLastError() == NTE_NO_KEY,
1552 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1553 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1554 ok(!result && GetLastError() == NTE_NO_KEY,
1555 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1556 CryptReleaseContext(prov, 0);
1557 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1559 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1560 CRYPT_DELETEKEYSET);
1561 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1562 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1563 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1564 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1565 CRYPT_VERIFYCONTEXT);
1566 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1567 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1568 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1569 CRYPT_NEWKEYSET);
1570 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1571 if (!result) return;
1572 /* Test provider parameters getter */
1573 dataLen = sizeof(dwParam);
1574 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1575 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1576 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1577 dataLen = sizeof(dwParam);
1578 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1579 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1580 "Expected 0, got 0x%08X\n",dwParam);
1581 dataLen = sizeof(dwParam);
1582 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1583 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1584 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1585 dataLen = sizeof(keySpec);
1586 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1587 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1588 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1589 /* PP_CONTAINER parameter */
1590 dataLen = sizeof(szName);
1591 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1592 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1593 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1594 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1595 /* PP_UNIQUE_CONTAINER parameter */
1596 dataLen = sizeof(szName);
1597 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1598 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1599 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1600 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1601 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1602 ok(!result && GetLastError() == NTE_NO_KEY,
1603 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1604 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1605 ok(!result && GetLastError() == NTE_NO_KEY,
1606 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1608 /* Importing a key exchange blob.. */
1609 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1610 0, 0, &key);
1611 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1612 CryptDestroyKey(key);
1613 /* allows access to the key exchange key.. */
1614 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1615 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1616 CryptDestroyKey(key);
1617 /* but not to the private key. */
1618 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1619 ok(!result && GetLastError() == NTE_NO_KEY,
1620 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1621 CryptReleaseContext(prov, 0);
1622 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1623 CRYPT_DELETEKEYSET);
1625 /* Whereas importing a sign blob.. */
1626 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1627 CRYPT_NEWKEYSET);
1628 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1629 if (!result) return;
1630 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1631 ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1632 /* doesn't allow access to the key exchange key.. */
1633 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1634 ok(!result && GetLastError() == NTE_NO_KEY,
1635 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1636 /* but does to the private key. */
1637 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1638 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1639 CryptDestroyKey(key);
1641 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1642 CRYPT_DELETEKEYSET);
1645 /* test for the bug in accessing the user key in a container
1647 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1648 CRYPT_NEWKEYSET);
1649 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1650 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1651 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1652 CryptDestroyKey(key);
1653 CryptReleaseContext(prov,0);
1654 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1655 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1656 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1657 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1658 CryptDestroyKey(key);
1660 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1661 CRYPT_DELETEKEYSET);
1663 /* test the machine key set */
1664 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1665 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1666 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1667 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1668 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1669 CryptReleaseContext(prov, 0);
1670 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1671 CRYPT_MACHINE_KEYSET);
1672 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1673 CryptReleaseContext(prov,0);
1674 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1675 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1676 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1677 GetLastError());
1678 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1679 CRYPT_MACHINE_KEYSET);
1680 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1681 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1685 START_TEST(rsaenh)
1687 if (!init_environment())
1688 return;
1689 test_prov();
1690 test_gen_random();
1691 test_hashes();
1692 test_rc4();
1693 test_rc2();
1694 test_des();
1695 test_3des112();
1696 test_3des();
1697 test_hmac();
1698 test_mac();
1699 test_block_cipher_modes();
1700 test_import_private();
1701 test_verify_signature();
1702 test_rsa_encrypt();
1703 test_import_export();
1704 test_enum_container();
1705 clean_up_environment();
1706 test_schannel_provider();
1707 test_null_provider();