rsaenh: Add tests of KP_SALT parameter.
[wine] / dlls / rsaenh / tests / rsaenh.c
1 /*
2  * Unit tests for rsaenh functions
3  *
4  * Copyright (c) 2004 Michael Jung
5  * Copyright (c) 2006 Juan Lang
6  * Copyright (c) 2007 Vijay Kiran Kamuju
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 #include <string.h>
24 #include <stdio.h>
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wincrypt.h"
30 #include "winreg.h"
31
32 static HCRYPTPROV hProv;
33 static const char szContainer[] = "winetest";
34 static const char szProvider[] = MS_ENHANCED_PROV_A;
35
36 typedef struct _ctdatatype {
37        unsigned char origstr[32];
38        unsigned char decstr[32];
39        int strlen;
40        int enclen;
41        int buflen;
42 } cryptdata;
43
44 static const cryptdata cTestData[4] = {
45        {"abcdefghijkl",
46        {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
47        12,8,16},
48        {"abcdefghij",
49        {'a','b','c','d','e','f','g','h',0x2,0x2,0},
50        10,8,16},
51        {"abcdefgh",
52        {'a','b','c','d','e','f','g','h',0},
53        8,8,16},
54        {"abcdefghijkl",
55        {'a','b','c','d','e','f','g','h','i','j','k','l',0},
56        12,12,16}
57 };
58
59 /*
60  * 1. Take the MD5 Hash of the container name (with an extra null byte)
61  * 2. Turn the hash into a 4 DWORD hex value
62  * 3. Append a '_'
63  * 4. Add the MachineGuid
64  *
65  */
66 static void uniquecontainer(char *unique)
67 {
68     /* MD5 hash of "winetest\0" in 4 DWORD hex */
69     static const char szContainer_md5[] = "9d20fd8d05ed2b8455d125d0bf6d6a70";
70     static const char szCryptography[] = "Software\\Microsoft\\Cryptography";
71     static const char szMachineGuid[] = "MachineGuid";
72     HKEY hkey;
73     char guid[MAX_PATH];
74     DWORD size = MAX_PATH;
75     HRESULT ret;
76
77     /* Get the MachineGUID */
78     ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szCryptography, 0, KEY_READ | KEY_WOW64_64KEY, &hkey);
79     if (ret == ERROR_ACCESS_DENIED)
80     {
81         /* Windows 2000 can't handle KEY_WOW64_64KEY */
82         RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
83     }
84     RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
85     RegCloseKey(hkey);
86
87     lstrcpy(unique, szContainer_md5);
88     lstrcat(unique, "_");
89     lstrcat(unique, guid);
90 }
91
92 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
93 {
94     size_t i;
95     printf("%s: ",heading);
96     for(i=0;i<cb;i++)
97         printf("0x%02x,",pb[i]);
98     putchar('\n');
99 }
100
101 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
102
103 /*
104 static void trace_hex(BYTE *pbData, DWORD dwLen) {
105     char szTemp[256];
106     DWORD i, j;
107
108     for (i = 0; i < dwLen-7; i+=8) {
109         sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", 
110             pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5], 
111             pbData[i+6], pbData[i+7]);
112         trace(szTemp);
113     }
114     for (j=0; i<dwLen; j++,i++) {
115         sprintf(szTemp+6*j, "0x%02x,\n", pbData[i]);
116     }
117     trace(szTemp);
118 }
119 */
120
121 static int init_base_environment(DWORD dwKeyFlags)
122 {
123     HCRYPTKEY hKey;
124     BOOL result;
125         
126     pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
127         
128     hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
129
130     result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
131     ok(!result && (GetLastError()==NTE_BAD_FLAGS ||
132        broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */)),
133        "%d, %08x\n", result, GetLastError());
134     
135     if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
136     {
137         ok(GetLastError()==NTE_BAD_KEYSET ||
138            broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */),
139            "%08x\n", GetLastError());
140         if (GetLastError()!=NTE_BAD_KEYSET)
141         {
142             win_skip("RSA full provider not available\n");
143             return 0;
144         }
145         result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 
146                                      CRYPT_NEWKEYSET);
147         ok(result, "%08x\n", GetLastError());
148         if (!result)
149         {
150             win_skip("Couldn't create crypto provider\n");
151             return 0;
152         }
153         result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey);
154         ok(result, "%08x\n", GetLastError());
155         if (result) CryptDestroyKey(hKey);
156         result = CryptGenKey(hProv, AT_SIGNATURE, dwKeyFlags, &hKey);
157         ok(result, "%08x\n", GetLastError());
158         if (result) CryptDestroyKey(hKey);
159     }
160     return 1;
161 }
162
163 static void clean_up_base_environment(void)
164 {
165     BOOL result;
166
167     SetLastError(0xdeadbeef);
168     result = CryptReleaseContext(hProv, 1);
169     ok(!result || broken(result) /* Win98 */, "Expected failure\n");
170     ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
171         
172     /* Just to prove that Win98 also released the CSP */
173     SetLastError(0xdeadbeef);
174     result = CryptReleaseContext(hProv, 0);
175     ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
176
177     CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
178 }
179
180 static int init_aes_environment(void)
181 {
182     HCRYPTKEY hKey;
183     BOOL result;
184
185     pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
186
187     hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
188
189     /* we are using NULL as provider name for RSA_AES provider as the provider
190      * names are different in Windows XP and Vista. Its different as to what
191      * its defined in the SDK on Windows XP.
192      * This provider is available on Windows XP, Windows 2003 and Vista.      */
193
194     result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
195     if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
196     {
197         win_skip("RSA_AES provider not supported\n");
198         return 0;
199     }
200     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
201
202     if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
203     {
204         ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
205         if (GetLastError()!=NTE_BAD_KEYSET) return 0;
206         result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
207                                      CRYPT_NEWKEYSET);
208         ok(result, "%08x\n", GetLastError());
209         if (!result) return 0;
210         result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
211         ok(result, "%08x\n", GetLastError());
212         if (result) CryptDestroyKey(hKey);
213         result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
214         ok(result, "%08x\n", GetLastError());
215         if (result) CryptDestroyKey(hKey);
216     }
217     return 1;
218 }
219
220 static void clean_up_aes_environment(void)
221 {
222     BOOL result;
223
224     result = CryptReleaseContext(hProv, 1);
225     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
226
227     CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
228 }
229
230 static void test_prov(void) 
231 {
232     BOOL result;
233     DWORD dwLen, dwInc;
234     
235     dwLen = (DWORD)sizeof(DWORD);
236     SetLastError(0xdeadbeef);
237     result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
238     if (!result && GetLastError() == NTE_BAD_TYPE)
239         skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
240     else
241         ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
242     
243     dwLen = (DWORD)sizeof(DWORD);
244     SetLastError(0xdeadbeef);
245     result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
246     if (!result && GetLastError() == NTE_BAD_TYPE)
247         skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
248     else
249         ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
250 }
251
252 static void test_gen_random(void)
253 {
254     BOOL result;
255     BYTE rnd1[16], rnd2[16];
256
257     memset(rnd1, 0, sizeof(rnd1));
258     memset(rnd2, 0, sizeof(rnd2));
259
260     result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
261     if (!result && GetLastError() == NTE_FAIL) {
262         /* rsaenh compiled without OpenSSL */
263         return;
264     }
265     
266     ok(result, "%08x\n", GetLastError());
267
268     result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
269     ok(result, "%08x\n", GetLastError());
270
271     ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
272 }
273
274 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len) 
275 {
276     HCRYPTHASH hHash;
277     BOOL result;
278     unsigned char pbData[2000];
279     int i;
280
281     *phKey = 0;
282     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
283     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
284     if (!result) {
285         /* rsaenh compiled without OpenSSL */
286         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
287         return FALSE;
288     } 
289     ok(result, "%08x\n", GetLastError());
290     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
291     ok(result, "%08x\n", GetLastError());
292     if (!result) return FALSE;
293     result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
294     ok(result, "%08x\n", GetLastError());
295     if (!result) return FALSE;
296     len = 2000;
297     result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
298     ok(result, "%08x\n", GetLastError());
299     CryptDestroyHash(hHash);
300     return TRUE;
301 }
302
303 static void test_hashes(void)
304 {
305     static const unsigned char md2hash[16] = {
306         0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9, 
307         0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
308     static const unsigned char md4hash[16] = {
309         0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23, 
310         0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
311     static const unsigned char empty_md5hash[16] = {
312         0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
313         0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
314     static const unsigned char md5hash[16] = { 
315         0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd, 
316         0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };    
317     static const unsigned char sha1hash[20] = { 
318         0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d, 
319         0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
320     unsigned char pbData[2048];
321     BOOL result;
322     HCRYPTHASH hHash, hHashClone;
323     BYTE pbHashValue[36];
324     DWORD hashlen, len;
325     int i;
326
327     for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
328
329     /* MD2 Hashing */
330     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
331     if (!result) {
332         /* rsaenh compiled without OpenSSL */
333         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
334     } else {
335         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
336         ok(result, "%08x\n", GetLastError());
337
338         len = sizeof(DWORD);
339         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
340            ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
341
342         len = 16;
343         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
344         ok(result, "%08x\n", GetLastError());
345
346         ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
347
348         result = CryptDestroyHash(hHash);
349         ok(result, "%08x\n", GetLastError());
350     } 
351
352     /* MD4 Hashing */
353     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
354     ok(result, "%08x\n", GetLastError());
355
356     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
357     ok(result, "%08x\n", GetLastError());
358
359     len = sizeof(DWORD);
360     result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
361     ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
362
363     len = 16;
364     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
365     ok(result, "%08x\n", GetLastError());
366
367     ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
368
369     result = CryptDestroyHash(hHash);
370     ok(result, "%08x\n", GetLastError());
371
372     /* MD5 Hashing */
373     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
374     ok(result, "%08x\n", GetLastError());
375
376     len = sizeof(DWORD);
377     result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
378     ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
379
380     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
381     ok(result, "%08x\n", GetLastError());
382
383     len = 16;
384     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
385     ok(result, "%08x\n", GetLastError());
386
387     ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
388
389     result = CryptDestroyHash(hHash);
390     ok(result, "%08x\n", GetLastError());
391
392     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
393     ok(result, "%08x\n", GetLastError());
394
395     /* The hash is available even if CryptHashData hasn't been called */
396     len = 16;
397     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
398     ok(result, "%08x\n", GetLastError());
399
400     ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
401
402     /* It's also stable:  getting it twice results in the same value */
403     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
404     ok(result, "%08x\n", GetLastError());
405
406     ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
407
408     /* Can't add data after the hash been retrieved */
409     SetLastError(0xdeadbeef);
410     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
411     ok(!result, "Expected failure\n");
412     ok(GetLastError() == NTE_BAD_HASH_STATE ||
413        GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
414        "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
415
416     /* You can still retrieve the hash, its value just hasn't changed */
417     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
418     ok(result, "%08x\n", GetLastError());
419
420     ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
421
422     result = CryptDestroyHash(hHash);
423     ok(result, "%08x\n", GetLastError());
424
425     /* SHA1 Hashing */
426     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
427     ok(result, "%08x\n", GetLastError());
428
429     result = CryptHashData(hHash, pbData, 5, 0);
430     ok(result, "%08x\n", GetLastError());
431
432     if(pCryptDuplicateHash) {
433         result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
434         ok(result, "%08x\n", GetLastError());
435
436         result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
437         ok(result, "%08x\n", GetLastError());
438
439         len = sizeof(DWORD);
440         result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
441         ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
442
443         len = 20;
444         result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
445         ok(result, "%08x\n", GetLastError());
446
447         ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
448
449         result = CryptDestroyHash(hHashClone);
450         ok(result, "%08x\n", GetLastError());
451     }
452
453     result = CryptDestroyHash(hHash);
454     ok(result, "%08x\n", GetLastError());
455
456     /* The SHA-2 variants aren't supported in the RSA full provider */
457     result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
458     ok(!result && GetLastError() == NTE_BAD_ALGID,
459        "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
460     result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
461     ok(!result && GetLastError() == NTE_BAD_ALGID,
462        "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
463     result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
464     ok(!result && GetLastError() == NTE_BAD_ALGID,
465        "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
466 }
467
468 static void test_block_cipher_modes(void)
469 {
470     static const BYTE plain[23] = { 
471         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 
472         0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
473     static const BYTE ecb[24] = {   
474         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f, 
475         0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
476     static const BYTE cbc[24] = {   
477         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
478         0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
479     static const BYTE cfb[24] = {   
480         0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
481         0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
482     HCRYPTKEY hKey;
483     BOOL result;
484     BYTE abData[24];
485     DWORD dwMode, dwLen;
486
487     result = derive_key(CALG_RC2, &hKey, 40);
488     if (!result) return;
489
490     memcpy(abData, plain, sizeof(plain));
491
492     dwMode = CRYPT_MODE_ECB;
493     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
494     ok(result, "%08x\n", GetLastError());
495
496     result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
497     ok(result, "%08x\n", GetLastError());
498     ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
499
500     dwLen = 23;
501     result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
502     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
503     ok(dwLen == 24, "Unexpected length %d\n", dwLen);
504
505     SetLastError(ERROR_SUCCESS);
506     dwLen = 23;
507     result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
508     ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)), 
509        "%08x, dwLen: %d\n", GetLastError(), dwLen);
510
511     result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
512     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)), 
513        "%08x, dwLen: %d\n", GetLastError(), dwLen);
514
515     dwMode = CRYPT_MODE_CBC;
516     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
517     ok(result, "%08x\n", GetLastError());
518     
519     dwLen = 23;
520     result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
521     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
522     ok(dwLen == 24, "Unexpected length %d\n", dwLen);
523
524     dwLen = 23;
525     result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
526     ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)), 
527        "%08x, dwLen: %d\n", GetLastError(), dwLen);
528
529     result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
530     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)), 
531        "%08x, dwLen: %d\n", GetLastError(), dwLen);
532
533     dwMode = CRYPT_MODE_CFB;
534     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
535     ok(result, "%08x\n", GetLastError());
536     
537     dwLen = 16;
538     result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
539     ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
540
541     dwLen = 7;
542     result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
543     ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)), 
544        "%08x, dwLen: %d\n", GetLastError(), dwLen);
545     
546     dwLen = 8;
547     result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
548     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
549
550     dwLen = 16;
551     result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
552     ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)), 
553        "%08x, dwLen: %d\n", GetLastError(), dwLen);
554
555     dwMode = CRYPT_MODE_OFB;
556     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
557     ok(result, "%08x\n", GetLastError());
558     
559     dwLen = 23;
560     result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
561     ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
562
563     CryptDestroyKey(hKey);
564 }
565
566 static void test_3des112(void)
567 {
568     HCRYPTKEY hKey;
569     BOOL result;
570     DWORD dwLen;
571     unsigned char pbData[16];
572     int i;
573
574     result = derive_key(CALG_3DES_112, &hKey, 0);
575     if (!result) {
576         /* rsaenh compiled without OpenSSL */
577         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
578         return;
579     }
580
581     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
582     
583     dwLen = 13;
584     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
585     ok(result, "%08x\n", GetLastError());
586     
587     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
588     ok(result, "%08x\n", GetLastError());
589
590     for (i=0; i<4; i++)
591     {
592       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
593
594       dwLen = cTestData[i].enclen;
595       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
596       ok(result, "%08x\n", GetLastError());
597       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
598
599       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
600       ok(result, "%08x\n", GetLastError());
601       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
602       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
603       if((dwLen != cTestData[i].enclen) ||
604          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
605       {
606           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
607           printBytes("got",pbData,dwLen);
608       }
609     }
610     result = CryptDestroyKey(hKey);
611     ok(result, "%08x\n", GetLastError());
612 }
613
614 static void test_des(void) 
615 {
616     HCRYPTKEY hKey;
617     BOOL result;
618     DWORD dwLen, dwMode;
619     unsigned char pbData[16];
620     int i;
621
622     result = derive_key(CALG_DES, &hKey, 56);
623     if (!result) {
624         /* rsaenh compiled without OpenSSL */
625         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
626         return;
627     }
628
629     dwMode = CRYPT_MODE_ECB;
630     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
631     ok(result, "%08x\n", GetLastError());
632     
633     dwLen = sizeof(DWORD);
634     result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
635     ok(result, "%08x\n", GetLastError());
636     
637     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
638     
639     dwLen = 13;
640     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
641     ok(result, "%08x\n", GetLastError());
642     
643     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
644     ok(result, "%08x\n", GetLastError());
645
646     for (i=0; i<4; i++)
647     {
648       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
649
650       dwLen = cTestData[i].enclen;
651       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
652       ok(result, "%08x\n", GetLastError());
653       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
654
655       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
656       ok(result, "%08x\n", GetLastError());
657       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
658       ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
659       if((dwLen != cTestData[i].enclen) ||
660          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
661       {
662           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
663           printBytes("got",pbData,dwLen);
664       }
665     }
666
667     result = CryptDestroyKey(hKey);
668     ok(result, "%08x\n", GetLastError());
669 }
670
671 static void test_3des(void)
672 {
673     HCRYPTKEY hKey;
674     BOOL result;
675     DWORD dwLen;
676     unsigned char pbData[16];
677     static const BYTE des3[16] = { 
678         0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3, 
679         0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
680     int i;
681
682     result = derive_key(CALG_3DES, &hKey, 0);
683     if (!result) return;
684
685     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
686     
687     dwLen = 13;
688     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
689     ok(result, "%08x\n", GetLastError());
690
691     ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
692
693     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
694     ok(result, "%08x\n", GetLastError());
695
696     for (i=0; i<4; i++)
697     {
698       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
699
700       dwLen = cTestData[i].enclen;
701       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
702       ok(result, "%08x\n", GetLastError());
703       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
704
705       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
706       ok(result, "%08x\n", GetLastError());
707       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
708       ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
709       if((dwLen != cTestData[i].enclen) ||
710          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
711       {
712           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
713           printBytes("got",pbData,dwLen);
714       }
715     }
716     result = CryptDestroyKey(hKey);
717     ok(result, "%08x\n", GetLastError());
718 }
719
720 static void test_aes(int keylen)
721 {
722     HCRYPTKEY hKey;
723     BOOL result;
724     DWORD dwLen;
725     unsigned char pbData[16];
726     int i;
727
728     switch (keylen)
729     {
730         case 256:
731             result = derive_key(CALG_AES_256, &hKey, 0);
732             break;
733         case 192:
734             result = derive_key(CALG_AES_192, &hKey, 0);
735             break;
736         default:
737         case 128:
738             result = derive_key(CALG_AES_128, &hKey, 0);
739             break;
740     }
741     if (!result) return;
742
743     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
744
745     /* AES provider doesn't support salt */
746     result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
747     todo_wine
748     ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == ERROR_NO_TOKEN /* Win7 */),
749        "expected NTE_BAD_KEY or ERROR_NO_TOKEN, got %08x\n", GetLastError());
750
751     dwLen = 13;
752     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
753     ok(result, "%08x\n", GetLastError());
754
755     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
756     ok(result, "%08x\n", GetLastError());
757
758     for (i=0; i<4; i++)
759     {
760       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
761
762       dwLen = cTestData[i].enclen;
763       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
764       ok(result, "%08x\n", GetLastError());
765       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
766
767       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
768       ok(result, "%08x\n", GetLastError());
769       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
770       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
771       if((dwLen != cTestData[i].enclen) ||
772          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
773       {
774           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
775           printBytes("got",pbData,dwLen);
776       }
777     }
778     result = CryptDestroyKey(hKey);
779     ok(result, "%08x\n", GetLastError());
780 }
781
782 static void test_sha2(void)
783 {
784     static const unsigned char sha256hash[32] = {
785         0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
786         0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
787         0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
788         0x1a, 0x08
789     };
790     static const unsigned char sha384hash[48] = {
791         0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
792         0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
793         0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
794         0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
795         0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
796     };
797     static const unsigned char sha512hash[64] = {
798         0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
799         0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
800         0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
801         0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
802         0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
803         0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
804         0xb7, 0xf4, 0x81, 0xd4
805     };
806     unsigned char pbData[2048];
807     BOOL result;
808     HCRYPTHASH hHash;
809     BYTE pbHashValue[64];
810     DWORD hashlen, len;
811     int i;
812
813     for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
814
815     /* SHA-256 hash */
816     SetLastError(0xdeadbeef);
817     result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
818     if (!result && GetLastError() == NTE_BAD_ALGID) {
819         win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
820         return;
821     }
822     ok(result, "%08x\n", GetLastError());
823     if (result) {
824         len = sizeof(DWORD);
825         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
826         ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
827
828         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
829         ok(result, "%08x\n", GetLastError());
830
831         len = 32;
832         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
833         ok(result, "%08x\n", GetLastError());
834
835         ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
836
837         result = CryptDestroyHash(hHash);
838         ok(result, "%08x\n", GetLastError());
839     }
840
841     /* SHA-384 hash */
842     result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
843     ok(result, "%08x\n", GetLastError());
844     if (result) {
845         len = sizeof(DWORD);
846         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
847         ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
848
849         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
850         ok(result, "%08x\n", GetLastError());
851
852         len = 48;
853         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
854         ok(result, "%08x\n", GetLastError());
855
856         ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
857
858         result = CryptDestroyHash(hHash);
859         ok(result, "%08x\n", GetLastError());
860     }
861
862     /* SHA-512 hash */
863     result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
864     ok(result, "%08x\n", GetLastError());
865     if (result) {
866         len = sizeof(DWORD);
867         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
868         ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
869
870         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
871         ok(result, "%08x\n", GetLastError());
872
873         len = 64;
874         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
875         ok(result, "%08x\n", GetLastError());
876
877         ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
878
879         result = CryptDestroyHash(hHash);
880         ok(result, "%08x\n", GetLastError());
881     }
882 }
883
884 static void test_rc2(void)
885 {
886     static const BYTE rc2_40_encrypted[16] = {
887         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
888         0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
889     static const BYTE rc2_128_encrypted[] = {
890         0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
891         0xb6,0x66 };
892     HCRYPTHASH hHash;
893     HCRYPTKEY hKey;
894     BOOL result;
895     DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
896     BYTE *pbTemp;
897     unsigned char pbData[2000], pbHashValue[16];
898     int i;
899     
900     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
901
902     /* MD2 Hashing */
903     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
904     if (!result) {
905         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
906     } else {
907         CRYPT_INTEGER_BLOB salt;
908
909         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
910         ok(result, "%08x\n", GetLastError());
911
912         dwLen = 16;
913         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
914         ok(result, "%08x\n", GetLastError());
915
916         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
917         ok(result, "%08x\n", GetLastError());
918
919         dwLen = sizeof(DWORD);
920         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
921         ok(result, "%08x\n", GetLastError());
922
923         dwMode = CRYPT_MODE_CBC;
924         result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
925         ok(result, "%08x\n", GetLastError());
926
927         dwLen = sizeof(DWORD);
928         result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
929         ok(result, "%08x\n", GetLastError());
930
931         dwModeBits = 0xdeadbeef;
932         dwLen = sizeof(DWORD);
933         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
934         ok(result, "%08x\n", GetLastError());
935         ok(dwModeBits ==
936             (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
937             broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
938             "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
939             " got %08x\n", dwModeBits);
940
941         dwLen = sizeof(DWORD);
942         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
943         ok(result, "%08x\n", GetLastError());
944
945         dwLen = sizeof(DWORD);
946         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
947         ok(result, "%08x\n", GetLastError());
948
949         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
950         ok(result, "%08x\n", GetLastError());
951         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
952         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
953         HeapFree(GetProcessHeap(), 0, pbTemp);
954
955         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
956         ok(result, "%08x\n", GetLastError());
957         /* The default salt length is always 11... */
958         ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
959         /* and the default salt is always empty. */
960         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
961         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
962         for (i=0; i<dwLen; i++)
963             ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
964         HeapFree(GetProcessHeap(), 0, pbTemp);
965
966         dwLen = sizeof(DWORD);
967         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
968
969         result = CryptDestroyHash(hHash);
970         ok(result, "%08x\n", GetLastError());
971
972         dwDataLen = 13;
973         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
974         ok(result, "%08x\n", GetLastError());
975
976         ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
977
978         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
979         ok(result, "%08x\n", GetLastError());
980         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
981         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
982         HeapFree(GetProcessHeap(), 0, pbTemp);
983
984         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
985         ok(result, "%08x\n", GetLastError());
986
987         /* Setting the salt also succeeds... */
988         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
989         todo_wine
990         ok(result, "setting salt failed: %08x\n", GetLastError());
991         /* but the resulting salt length is now zero? */
992         dwLen = 0;
993         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
994         ok(result, "%08x\n", GetLastError());
995         todo_wine
996         ok(dwLen == 0, "unexpected salt length %d\n", dwLen);
997         /* What sizes salt can I set? */
998         salt.pbData = pbData;
999         for (i=0; i<24; i++)
1000         {
1001             salt.cbData = i;
1002             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1003             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1004             /* The returned salt length is the same as the set salt length */
1005             result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1006             ok(result, "%08x\n", GetLastError());
1007             ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1008         }
1009         salt.cbData = 25;
1010         SetLastError(0xdeadbeef);
1011         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1012         ok(!result ||
1013            broken(result), /* Win9x, WinMe, NT4, W2K */
1014            "%08x\n", GetLastError());
1015
1016         result = CryptDestroyKey(hKey);
1017         ok(result, "%08x\n", GetLastError());
1018     }
1019
1020     /* Again, but test setting the effective key len */
1021     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1022
1023     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1024     if (!result) {
1025         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1026     } else {
1027         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1028         ok(result, "%08x\n", GetLastError());
1029
1030         dwLen = 16;
1031         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1032         ok(result, "%08x\n", GetLastError());
1033
1034         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1035         ok(result, "%08x\n", GetLastError());
1036
1037         SetLastError(0xdeadbeef);
1038         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1039         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1040         dwKeyLen = 0;
1041         SetLastError(0xdeadbeef);
1042         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1043         ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1044         dwKeyLen = 1025;
1045         SetLastError(0xdeadbeef);
1046         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1047
1048         dwLen = sizeof(dwKeyLen);
1049         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1050         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1051         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1052         ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1053
1054         dwKeyLen = 128;
1055         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1056         ok(result, "%d\n", GetLastError());
1057
1058         dwLen = sizeof(dwKeyLen);
1059         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1060         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1061         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1062         ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1063
1064         result = CryptDestroyHash(hHash);
1065         ok(result, "%08x\n", GetLastError());
1066
1067         dwDataLen = 13;
1068         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1069         ok(result, "%08x\n", GetLastError());
1070
1071         ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1072                 "RC2 encryption failed!\n");
1073
1074         /* Oddly enough this succeeds, though it should have no effect */
1075         dwKeyLen = 40;
1076         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1077         ok(result, "%d\n", GetLastError());
1078
1079         result = CryptDestroyKey(hKey);
1080         ok(result, "%08x\n", GetLastError());
1081     }
1082 }
1083
1084 static void test_rc4(void)
1085 {
1086     static const BYTE rc4[16] = { 
1087         0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0, 
1088         0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };    
1089     BOOL result;
1090     HCRYPTHASH hHash;
1091     HCRYPTKEY hKey;
1092     DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1093     unsigned char pbData[2000], *pbTemp;
1094     unsigned char pszBuffer[256];
1095     int i;
1096
1097     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1098
1099     /* MD2 Hashing */
1100     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1101     if (!result) {
1102         /* rsaenh compiled without OpenSSL */
1103         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1104     } else {
1105         CRYPT_INTEGER_BLOB salt;
1106
1107         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1108            ok(result, "%08x\n", GetLastError());
1109
1110         dwLen = 16;
1111         result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1112         ok(result, "%08x\n", GetLastError());
1113
1114         result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1115         ok(result, "%08x\n", GetLastError());
1116
1117         dwLen = sizeof(DWORD);
1118         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1119         ok(result, "%08x\n", GetLastError());
1120
1121         dwLen = sizeof(DWORD);
1122         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1123         ok(result, "%08x\n", GetLastError());
1124
1125         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1126         ok(result, "%08x\n", GetLastError());
1127         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1128         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1129         HeapFree(GetProcessHeap(), 0, pbTemp);
1130
1131         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1132         ok(result, "%08x\n", GetLastError());
1133         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1134         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1135         HeapFree(GetProcessHeap(), 0, pbTemp);
1136
1137         dwLen = sizeof(DWORD);
1138         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1139
1140         result = CryptDestroyHash(hHash);
1141         ok(result, "%08x\n", GetLastError());
1142
1143         dwDataLen = 16;
1144         result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1145         ok(result, "%08x\n", GetLastError());
1146         dwDataLen = 16;
1147         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1148         ok(result, "%08x\n", GetLastError());
1149
1150         ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1151
1152         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1153         ok(result, "%08x\n", GetLastError());
1154
1155         /* Setting the salt also succeeds... */
1156         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1157         todo_wine
1158         ok(result, "setting salt failed: %08x\n", GetLastError());
1159         /* but the resulting salt length is now zero? */
1160         dwLen = 0;
1161         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1162         ok(result, "%08x\n", GetLastError());
1163         ok(dwLen == 0, "unexpected salt length %d\n", dwLen);
1164         /* What sizes salt can I set? */
1165         salt.pbData = pbData;
1166         for (i=0; i<24; i++)
1167         {
1168             salt.cbData = i;
1169             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1170             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1171             /* The returned salt length is the same as the set salt length */
1172             result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1173             ok(result, "%08x\n", GetLastError());
1174             ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1175         }
1176         salt.cbData = 25;
1177         SetLastError(0xdeadbeef);
1178         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1179         ok(!result ||
1180            broken(result), /* Win9x, WinMe, NT4, W2K */
1181            "%08x\n", GetLastError());
1182
1183         result = CryptDestroyKey(hKey);
1184         ok(result, "%08x\n", GetLastError());
1185     }
1186 }
1187
1188 static void test_hmac(void) {
1189     HCRYPTKEY hKey;
1190     HCRYPTHASH hHash;
1191     BOOL result;
1192     /* Using CALG_MD2 here fails on Windows 2003, why ? */
1193     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1194     DWORD dwLen;
1195     BYTE abData[256];
1196     static const BYTE hmac[16] = { 
1197         0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c, 
1198         0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1199     int i;
1200
1201     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1202
1203     if (!derive_key(CALG_RC2, &hKey, 56)) return;
1204
1205     result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1206     ok(result, "%08x\n", GetLastError());
1207     if (!result) return;
1208
1209     result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1210     ok(result, "%08x\n", GetLastError());
1211
1212     result = CryptHashData(hHash, abData, sizeof(abData), 0);
1213     ok(result, "%08x\n", GetLastError());
1214
1215     dwLen = sizeof(abData)/sizeof(BYTE);
1216     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1217     ok(result, "%08x\n", GetLastError());
1218
1219     ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1220     
1221     result = CryptDestroyHash(hHash);
1222     ok(result, "%08x\n", GetLastError());
1223     
1224     result = CryptDestroyKey(hKey);
1225     ok(result, "%08x\n", GetLastError());
1226
1227     /* Provoke errors */
1228     result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1229     ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1230 }
1231
1232 static void test_mac(void) {
1233     HCRYPTKEY hKey;
1234     HCRYPTHASH hHash;
1235     BOOL result;
1236     DWORD dwLen;
1237     BYTE abData[256], abEnc[264];
1238     static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1239     int i;
1240
1241     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1242     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1243
1244     if (!derive_key(CALG_RC2, &hKey, 40)) return;
1245
1246     dwLen = 256;
1247     result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1248     ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1249     
1250     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1251     ok(result, "%08x\n", GetLastError());
1252     if (!result) return;
1253
1254     result = CryptHashData(hHash, abData, sizeof(abData), 0);
1255     ok(result, "%08x\n", GetLastError());
1256
1257     dwLen = sizeof(abData)/sizeof(BYTE);
1258     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1259     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1260
1261     ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1262     
1263     result = CryptDestroyHash(hHash);
1264     ok(result, "%08x\n", GetLastError());
1265     
1266     result = CryptDestroyKey(hKey);
1267     ok(result, "%08x\n", GetLastError());
1268     
1269     /* Provoke errors */
1270     if (!derive_key(CALG_RC4, &hKey, 56)) return;
1271
1272     SetLastError(0xdeadbeef);
1273     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1274     ok((!result && GetLastError() == NTE_BAD_KEY) ||
1275             broken(result), /* Win9x, WinMe, NT4, W2K */
1276             "%08x\n", GetLastError());
1277
1278     result = CryptDestroyKey(hKey);
1279     ok(result, "%08x\n", GetLastError());
1280 }
1281
1282 static BYTE abPlainPrivateKey[596] = {
1283     0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1284     0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1285     0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1286     0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1287     0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1288     0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1289     0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1290     0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1291     0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1292     0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1293     0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1294     0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1295     0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1296     0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1297     0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1298     0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1299     0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1300     0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1301     0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1302     0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1303     0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1304     0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1305     0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1306     0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1307     0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1308     0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1309     0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1310     0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1311     0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1312     0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1313     0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1314     0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1315     0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1316     0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1317     0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1318     0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1319     0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1320     0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1321     0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1322     0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1323     0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1324     0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1325     0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1326     0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1327     0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1328     0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1329     0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1330     0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1331     0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1332     0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1333     0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1334     0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1335     0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1336     0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1337     0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1338     0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1339     0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1340     0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1341     0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1342     0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1343     0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1344     0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1345     0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1346     0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1347     0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1348     0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1349     0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1350     0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1351     0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1352     0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1353     0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1354     0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1355     0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1356     0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1357     0xf2, 0x5d, 0x58, 0x07
1358 };
1359
1360 static void test_import_private(void) 
1361 {
1362     DWORD dwLen, dwVal;
1363     HCRYPTKEY hKeyExchangeKey, hSessionKey;
1364     BOOL result;
1365     static BYTE abSessionKey[148] = {
1366         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1367         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1368         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1369         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1370         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1371         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1372         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1373         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1374         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1375         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1376         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1377         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1378         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1379         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1380         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1381         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1382         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1383         0x04, 0x8c, 0x49, 0x92
1384     };
1385     static BYTE abEncryptedMessage[12] = {
1386         0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1387         0x1c, 0xfd, 0xde, 0x71
1388     };
1389             
1390     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1391     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1392     if (!result) {
1393         /* rsaenh compiled without OpenSSL */
1394         ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1395         return;
1396     }
1397
1398     dwLen = (DWORD)sizeof(abSessionKey);
1399     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1400     ok(result, "%08x\n", GetLastError());
1401     if (!result) return;
1402
1403     dwVal = 0xdeadbeef;
1404     dwLen = sizeof(DWORD);
1405     result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1406     ok(result, "%08x\n", GetLastError());
1407     ok(dwVal ==
1408         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1409         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1410         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1411         " got %08x\n", dwVal);
1412
1413     dwLen = (DWORD)sizeof(abEncryptedMessage);
1414     result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1415     ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12), 
1416        "%08x, len: %d\n", GetLastError(), dwLen);
1417     CryptDestroyKey(hSessionKey);
1418     
1419     if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1420
1421     dwLen = (DWORD)sizeof(abSessionKey);
1422     result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1423     ok(result, "%08x\n", GetLastError());
1424     CryptDestroyKey(hSessionKey);
1425     if (!result) return;
1426
1427     dwLen = (DWORD)sizeof(abSessionKey);
1428     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1429     ok(result, "%08x\n", GetLastError());
1430     if (!result) return;
1431
1432     CryptDestroyKey(hSessionKey);
1433     CryptDestroyKey(hKeyExchangeKey);
1434 }
1435
1436 static void test_verify_signature(void) {
1437     HCRYPTHASH hHash;
1438     HCRYPTKEY hPubSignKey;
1439     BYTE abData[] = "Wine rocks!";
1440     BOOL result;
1441     BYTE abPubKey[148] = {
1442         0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 
1443         0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 
1444         0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19, 
1445         0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27, 
1446         0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8, 
1447         0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda, 
1448         0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a, 
1449         0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc, 
1450         0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c, 
1451         0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c, 
1452         0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89, 
1453         0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b, 
1454         0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa, 
1455         0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63, 
1456         0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff, 
1457         0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49, 
1458         0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87, 
1459         0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7, 
1460         0xe1, 0x21, 0x50, 0xac
1461     };
1462     /* md2 with hash oid */
1463     BYTE abSignatureMD2[128] = {
1464         0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67, 
1465         0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b, 
1466         0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda, 
1467         0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59, 
1468         0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a, 
1469         0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34, 
1470         0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40, 
1471         0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7, 
1472         0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0, 
1473         0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06, 
1474         0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51, 
1475         0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f, 
1476         0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46, 
1477         0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25, 
1478         0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0, 
1479         0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1480     };
1481     /* md2 without hash oid */
1482     BYTE abSignatureMD2NoOID[128] = {
1483         0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d, 
1484         0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19, 
1485         0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd, 
1486         0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4, 
1487         0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65, 
1488         0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99, 
1489         0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf, 
1490         0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc, 
1491         0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0, 
1492         0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01, 
1493         0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7, 
1494         0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f, 
1495         0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a, 
1496         0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9, 
1497         0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06, 
1498         0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1499     };
1500     /* md4 with hash oid */
1501     BYTE abSignatureMD4[128] = {
1502         0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51, 
1503         0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b, 
1504         0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2, 
1505         0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e, 
1506         0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13, 
1507         0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9, 
1508         0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f, 
1509         0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96, 
1510         0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9, 
1511         0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e, 
1512         0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0, 
1513         0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe, 
1514         0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18, 
1515         0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab, 
1516         0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3, 
1517         0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1518     };
1519     /* md4 without hash oid */
1520     BYTE abSignatureMD4NoOID[128] = {
1521         0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda, 
1522         0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24, 
1523         0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0, 
1524         0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36, 
1525         0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85, 
1526         0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3, 
1527         0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f, 
1528         0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9, 
1529         0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06, 
1530         0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f, 
1531         0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb, 
1532         0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96, 
1533         0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f, 
1534         0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9, 
1535         0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb, 
1536         0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1537     }; 
1538     /* md5 with hash oid */
1539     BYTE abSignatureMD5[128] = {
1540         0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5, 
1541         0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f, 
1542         0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7, 
1543         0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98, 
1544         0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec, 
1545         0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5, 
1546         0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04, 
1547         0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b, 
1548         0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95, 
1549         0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c, 
1550         0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29, 
1551         0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9, 
1552         0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c, 
1553         0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90, 
1554         0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e, 
1555         0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1556     };
1557     /* md5 without hash oid */
1558     BYTE abSignatureMD5NoOID[128] = {
1559         0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f, 
1560         0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75, 
1561         0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f, 
1562         0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d, 
1563         0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f, 
1564         0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49, 
1565         0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8, 
1566         0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c, 
1567         0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23, 
1568         0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19, 
1569         0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb, 
1570         0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3, 
1571         0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b, 
1572         0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b, 
1573         0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5, 
1574         0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1575     };
1576     /* sha with hash oid */
1577     BYTE abSignatureSHA[128] = {
1578         0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91, 
1579         0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd, 
1580         0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24, 
1581         0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94, 
1582         0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f, 
1583         0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a, 
1584         0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52, 
1585         0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20, 
1586         0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5, 
1587         0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a, 
1588         0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff, 
1589         0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53, 
1590         0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00, 
1591         0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e, 
1592         0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98, 
1593         0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1594     };
1595     /* sha without hash oid */
1596     BYTE abSignatureSHANoOID[128] = {
1597         0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6, 
1598         0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a, 
1599         0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f, 
1600         0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37, 
1601         0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65, 
1602         0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe, 
1603         0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6, 
1604         0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe, 
1605         0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c, 
1606         0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4, 
1607         0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80, 
1608         0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a, 
1609         0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00, 
1610         0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd, 
1611         0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67, 
1612         0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1613     }; 
1614     
1615     result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1616     ok(result, "%08x\n", GetLastError());
1617     if (!result) return;
1618
1619     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1620     ok(result, "%08x\n", GetLastError());
1621     if (!result) return;
1622
1623     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1624     ok(result, "%08x\n", GetLastError());
1625     if (!result) return;
1626
1627     /*check that a NULL pointer signature is correctly handled*/
1628     result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1629     ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1630      "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1631     if (result) return;
1632
1633     /* check that we get a bad signature error when the signature is too short*/
1634     SetLastError(0xdeadbeef);
1635     result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1636     ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1637      broken(result), /* Win9x, WinMe, NT4 */
1638      "Expected NTE_BAD_SIGNATURE, got %08x\n",  GetLastError());
1639
1640     result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1641     ok(result, "%08x\n", GetLastError());
1642     if (!result) return;
1643
1644     result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1645     ok(result, "%08x\n", GetLastError());
1646     if (!result) return;
1647
1648     /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about 
1649      * the OID at all. */
1650     /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1651     ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1652     if (result) return;*/
1653
1654     CryptDestroyHash(hHash);
1655
1656     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1657     ok(result, "%08x\n", GetLastError());
1658     if (!result) return;
1659
1660     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1661     ok(result, "%08x\n", GetLastError());
1662     if (!result) return;
1663
1664     result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1665     ok(result, "%08x\n", GetLastError());
1666     if (!result) return;
1667
1668     result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1669     ok(result, "%08x\n", GetLastError());
1670     if (!result) return;
1671
1672     CryptDestroyHash(hHash);
1673
1674     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1675     ok(result, "%08x\n", GetLastError());
1676     if (!result) return;
1677
1678     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1679     ok(result, "%08x\n", GetLastError());
1680     if (!result) return;
1681
1682     result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1683     ok(result, "%08x\n", GetLastError());
1684     if (!result) return;
1685
1686     result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1687     ok(result, "%08x\n", GetLastError());
1688     if (!result) return;
1689
1690     CryptDestroyHash(hHash);
1691
1692     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1693     ok(result, "%08x\n", GetLastError());
1694     if (!result) return;
1695
1696     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1697     ok(result, "%08x\n", GetLastError());
1698     if (!result) return;
1699
1700     result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1701     ok(result, "%08x\n", GetLastError());
1702     if (!result) return;
1703
1704     result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1705     ok(result, "%08x\n", GetLastError());
1706     if (!result) return;
1707
1708     CryptDestroyHash(hHash);
1709     CryptDestroyKey(hPubSignKey);
1710 }
1711
1712 static void test_rsa_encrypt(void)
1713 {
1714     HCRYPTKEY hRSAKey;
1715     BYTE abData[2048] = "Wine rocks!";
1716     BOOL result;
1717     DWORD dwVal, dwLen;
1718
1719     /* It is allowed to use the key exchange key for encryption/decryption */
1720     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1721     ok (result, "%08x\n", GetLastError());
1722     if (!result) return;
1723
1724     dwLen = 12;
1725     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1726     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1727     ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1728     dwLen = 12;
1729     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1730     ok (result, "%08x\n", GetLastError());
1731     if (!result) return;
1732
1733     result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1734     ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1735     
1736     dwVal = 0xdeadbeef;
1737     dwLen = sizeof(DWORD);
1738     result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1739     ok(result, "%08x\n", GetLastError());
1740     ok(dwVal ==
1741         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1742         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1743         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1744         " got %08x\n", dwVal);
1745
1746     /* An RSA key doesn't support salt */
1747     result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1748     todo_wine
1749     ok(!result && GetLastError() == NTE_BAD_KEY,
1750        "expected NTE_BAD_KEY, got %08x\n", GetLastError());
1751
1752     /* The key exchange key's public key may be exported.. */
1753     result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1754     ok(result, "%08x\n", GetLastError());
1755     /* but its private key may not be. */
1756     SetLastError(0xdeadbeef);
1757     result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1758     ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1759         broken(result), /* Win9x/NT4 */
1760         "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1761     /* Setting the permissions of the key exchange key isn't allowed, either. */
1762     dwVal |= CRYPT_EXPORT;
1763     SetLastError(0xdeadbeef);
1764     result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1765     ok(!result &&
1766         (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1767         "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1768
1769     CryptDestroyKey(hRSAKey);
1770
1771     /* It is not allowed to use the signature key for encryption/decryption */
1772     result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1773     ok (result, "%08x\n", GetLastError());
1774     if (!result) return;
1775
1776     dwVal = 0xdeadbeef;
1777     dwLen = sizeof(DWORD);
1778     result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1779     ok(result, "%08x\n", GetLastError());
1780     ok(dwVal ==
1781         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1782         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1783         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1784         " got %08x\n", dwVal);
1785
1786     /* The signature key's public key may also be exported.. */
1787     result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1788     ok(result, "%08x\n", GetLastError());
1789     /* but its private key may not be. */
1790     SetLastError(0xdeadbeef);
1791     result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1792     ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1793         broken(result), /* Win9x/NT4 */
1794         "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1795     /* Setting the permissions of the signature key isn't allowed, either. */
1796     dwVal |= CRYPT_EXPORT;
1797     SetLastError(0xdeadbeef);
1798     result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1799     ok(!result &&
1800         (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1801         "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1802
1803     dwLen = 12;
1804     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1805     ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1806
1807     CryptDestroyKey(hRSAKey);
1808 }
1809
1810 static void test_import_export(void)
1811 {
1812     DWORD dwLen, dwDataLen, dwVal;
1813     HCRYPTKEY hPublicKey, hPrivKey;
1814     BOOL result;
1815     ALG_ID algID;
1816     BYTE emptyKey[2048], *exported_key;
1817     static BYTE abPlainPublicKey[84] = {
1818         0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1819         0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1820         0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1821         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1822         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1823         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1824         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1825         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1826         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1827         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1828         0x11, 0x11, 0x11, 0x11
1829     };
1830     static BYTE priv_key_with_high_bit[] = {
1831         0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1832         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1833         0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1834         0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1835         0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1836         0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1837         0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1838         0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1839         0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1840         0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1841         0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1842         0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1843         0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1844         0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1845         0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1846         0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1847         0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1848         0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1849         0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1850         0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1851         0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1852         0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1853         0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1854         0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1855         0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1856         0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1857         0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1858         0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1859         0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1860         0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1861         0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1862         0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1863         0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1864         0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1865         0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1866         0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1867         0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1868         0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1869         0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1870         0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1871         0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1872         0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1873         0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1874         0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1875         0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1876         0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1877         0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1878         0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1879         0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1880         0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1881         0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1882         0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1883         0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1884         0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1885         0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1886         0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1887         0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1888         0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1889         0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1890         0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1891         0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1892         0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1893         0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1894         0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1895         0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1896         0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1897         0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1898         0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1899         0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1900         0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1901         0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1902         0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1903         0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1904         0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1905         0xb6, 0x5f, 0x01, 0x5e
1906     };
1907     static const BYTE expected_exported_priv_key[] = {
1908         0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1909         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1910         0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1911         0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1912         0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1913         0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1914         0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1915         0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1916         0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1917         0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1918         0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1919         0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1920         0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1921         0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1922         0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1923         0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1924         0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1925         0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1926         0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1927         0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1928         0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1929         0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1930         0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1931         0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1932         0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1933         0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1934         0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1935         0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1936         0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1937         0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1938         0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1939         0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1940         0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1941         0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1942         0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1943         0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1944         0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1945         0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1946         0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1947         0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1948         0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1949         0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1950         0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1951         0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1952         0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1953         0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1954         0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1955         0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1956         0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1957         0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1958         0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1959         0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1960         0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1961         0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1962         0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1963         0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1964         0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1965         0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1966         0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1967         0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1968         0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1969         0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1970         0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1971         0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1972         0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1973         0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1974         0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1975         0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1976         0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1977         0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1978         0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1979         0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1980         0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1981         0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1982         0xb6, 0x5f, 0x01, 0x5e
1983     };
1984
1985     dwLen=84;
1986     result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1987     ok(result, "failed to import the public key\n");
1988
1989     dwDataLen=sizeof(algID);
1990     result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1991     ok(result, "failed to get the KP_ALGID from the imported public key\n");
1992     ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1993         
1994     dwVal = 0xdeadbeef;
1995     dwDataLen = sizeof(DWORD);
1996     result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
1997     ok(result, "%08x\n", GetLastError());
1998     ok(dwVal ==
1999         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2000         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2001         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2002         " got %08x\n", dwVal);
2003     result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2004     ok(result, "failed to export the fresh imported public key\n");
2005     ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2006     ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2007
2008     CryptDestroyKey(hPublicKey);
2009
2010     result = CryptImportKey(hProv, priv_key_with_high_bit,
2011         sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2012     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2013
2014     result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2015     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2016     exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2017     result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2018         &dwDataLen);
2019     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2020
2021     ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2022         dwDataLen);
2023     ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2024         "unexpected value\n");
2025
2026     HeapFree(GetProcessHeap(), 0, exported_key);
2027
2028     CryptDestroyKey(hPrivKey);
2029 }
2030         
2031 static void test_schannel_provider(void)
2032 {
2033     HCRYPTPROV hProv;
2034     HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2035     HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2036     BOOL result;
2037     DWORD dwLen;
2038     SCHANNEL_ALG saSChannelAlg;
2039     CRYPT_DATA_BLOB data_blob;
2040     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2041     BYTE abTLS1Master[140] = {
2042         0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00, 
2043         0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68, 
2044         0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97, 
2045         0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53, 
2046         0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24, 
2047         0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3, 
2048         0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8, 
2049         0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d, 
2050         0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e, 
2051         0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e, 
2052         0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40, 
2053         0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b, 
2054         0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb, 
2055         0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6, 
2056         0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac, 
2057         0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41, 
2058         0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4, 
2059         0xd3, 0x1e, 0x82, 0xb3
2060     };
2061     BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2062     BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2063     BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2064     BYTE abClientFinished[16] = "client finished";
2065     BYTE abData[16] = "Wine rocks!";
2066     BYTE abMD5Hash[16];
2067     static const BYTE abEncryptedData[16] = {
2068         0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2069         0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d    
2070     };
2071     static const BYTE abPRF[16] = {
2072         0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2073         0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2074     };
2075     static const BYTE abMD5[16] = {
2076         0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2077         0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2078     };
2079     
2080     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2081     if (!result)
2082     {
2083         win_skip("no PROV_RSA_SCHANNEL support\n");
2084         return;
2085     }
2086     ok (result, "%08x\n", GetLastError());
2087     if (result)
2088         CryptReleaseContext(hProv, 0);
2089
2090     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2091     ok (result, "%08x\n", GetLastError());
2092     if (!result) return;
2093     
2094     /* To get deterministic results, we import the TLS1 master secret (which
2095      * is typically generated from a random generator). Therefore, we need
2096      * an RSA key. */
2097     dwLen = (DWORD)sizeof(abPlainPrivateKey);
2098     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2099     ok (result, "%08x\n", GetLastError());
2100     if (!result) return;
2101
2102     dwLen = (DWORD)sizeof(abTLS1Master);
2103     result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2104     ok (result, "%08x\n", GetLastError());
2105     if (!result) return;    
2106    
2107     /* Setting the TLS1 client and server random parameters, as well as the 
2108      * MAC and encryption algorithm parameters. */
2109     data_blob.cbData = 33;
2110     data_blob.pbData = abClientSecret;
2111     result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2112     ok (result, "%08x\n", GetLastError());
2113     if (!result) return;
2114
2115     data_blob.cbData = 33;
2116     data_blob.pbData = abServerSecret;
2117     result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2118     ok (result, "%08x\n", GetLastError());
2119     if (!result) return;
2120     
2121     saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2122     saSChannelAlg.Algid = CALG_DES;
2123     saSChannelAlg.cBits = 64;
2124     saSChannelAlg.dwFlags = 0;
2125     saSChannelAlg.dwReserved = 0;
2126     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2127     ok (result, "%08x\n", GetLastError());
2128     if (!result) return;
2129
2130     saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2131     saSChannelAlg.Algid = CALG_MD5;
2132     saSChannelAlg.cBits = 128;
2133     saSChannelAlg.dwFlags = 0;
2134     saSChannelAlg.dwReserved = 0;
2135     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2136     ok (result, "%08x\n", GetLastError());
2137     if (!result) return;
2138
2139     /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2140      * (Keys can only be derived from hashes, not from other keys.) */
2141     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2142     ok (result, "%08x\n", GetLastError());
2143     if (!result) return;
2144
2145     /* Deriving the server write encryption key from the master hash */
2146     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2147     ok (result, "%08x\n", GetLastError());
2148     if (!result) return;
2149
2150     /* Encrypting some data with the server write encryption key and checking the result. */
2151     dwLen = 12;
2152     result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2153     ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2154
2155     /* Second test case: Test the TLS1 pseudo random number function. */
2156     result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2157     ok (result, "%08x\n", GetLastError());
2158     if (!result) return;
2159
2160     /* Set the label and seed parameters for the random number function */
2161     data_blob.cbData = 36;
2162     data_blob.pbData = abHashedHandshakes;
2163     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2164     ok (result, "%08x\n", GetLastError());
2165     if (!result) return;
2166
2167     data_blob.cbData = 15;
2168     data_blob.pbData = abClientFinished;
2169     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2170     ok (result, "%08x\n", GetLastError());
2171     if (!result) return;
2172
2173     /* Generate some pseudo random bytes and check if they are correct. */
2174     dwLen = (DWORD)sizeof(abData);
2175     result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2176     ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)), 
2177         "%08x\n", GetLastError());
2178
2179     /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2180      * Hash some data with the HMAC. Compare results. */
2181     result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2182     ok (result, "%08x\n", GetLastError());
2183     if (!result) return;
2184     
2185     result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2186     ok (result, "%08x\n", GetLastError());
2187     if (!result) return;
2188
2189     result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2190     ok (result, "%08x\n", GetLastError());
2191     if (!result) return;
2192
2193     result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2194     ok (result, "%08x\n", GetLastError());
2195     if (!result) return;
2196
2197     dwLen = (DWORD)sizeof(abMD5Hash);
2198     result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2199     ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2200
2201     CryptDestroyHash(hHMAC);
2202     CryptDestroyHash(hTLS1PRF);
2203     CryptDestroyHash(hMasterHash);
2204     CryptDestroyKey(hServerWriteMACKey);
2205     CryptDestroyKey(hServerWriteKey);
2206     CryptDestroyKey(hRSAKey);
2207     CryptDestroyKey(hMasterSecret);
2208     CryptReleaseContext(hProv, 0);
2209     CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2210 }
2211
2212 /* Test that a key can be used to encrypt data and exported, and that, when
2213  * the exported key is imported again, can be used to decrypt the original
2214  * data again.
2215  */
2216 static void test_rsa_round_trip(void)
2217 {
2218     static const char test_string[] = "Well this is a fine how-do-you-do.";
2219     HCRYPTPROV prov;
2220     HCRYPTKEY signKey, keyExchangeKey;
2221     BOOL result;
2222     BYTE data[256], *exportedKey;
2223     DWORD dataLen, keyLen;
2224
2225     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2226      CRYPT_DELETEKEYSET);
2227
2228     /* Generate a new key... */
2229     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2230      CRYPT_NEWKEYSET);
2231     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2232     result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2233     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2234     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2235     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2236     /* encrypt some data with it... */
2237     memcpy(data, test_string, strlen(test_string) + 1);
2238     dataLen = strlen(test_string) + 1;
2239     result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2240                           sizeof(data));
2241     ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2242        "CryptEncrypt failed: %08x\n", GetLastError());
2243     /* export the key... */
2244     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2245                             &keyLen);
2246     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2247     exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2248     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2249                             &keyLen);
2250     /* destroy the key... */
2251     CryptDestroyKey(keyExchangeKey);
2252     CryptDestroyKey(signKey);
2253     /* import the key again... */
2254     result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2255     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2256     HeapFree(GetProcessHeap(), 0, exportedKey);
2257     /* and decrypt the data encrypted with the original key with the imported
2258      * key.
2259      */
2260     result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2261     ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2262        "CryptDecrypt failed: %08x\n", GetLastError());
2263     if (result)
2264     {
2265         ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2266         ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2267     }
2268     CryptDestroyKey(keyExchangeKey);
2269     CryptReleaseContext(prov, 0);
2270
2271     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2272      CRYPT_DELETEKEYSET);
2273 }
2274
2275 static void test_enum_container(void)
2276 {
2277     BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2278     DWORD dwBufferLen;
2279     BOOL result, fFound = FALSE;
2280
2281     /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2282      * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2283     SetLastError(0xdeadbeef);
2284     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2285     ok (result, "%08x\n", GetLastError());
2286     ok (dwBufferLen == MAX_PATH + 1 ||
2287         broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2288         "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2289
2290     /* If the result fits into abContainerName dwBufferLen is left untouched */
2291     dwBufferLen = (DWORD)sizeof(abContainerName);
2292     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2293     ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2294     
2295     /* We only check, if the currently open 'winetest' container is among the enumerated. */
2296     do {
2297         if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2298         dwBufferLen = (DWORD)sizeof(abContainerName);
2299     } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2300         
2301     ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2302 }
2303
2304 static BYTE signBlob[] = {
2305 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2306 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2307 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2308 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2309 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2310 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2311 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2312 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2313 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2314 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2315 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2316 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2317 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2318 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2319 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2320 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2321 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2322 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2323 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2324 0xb6,0x85,0x86,0x07 };
2325
2326 static void test_null_provider(void)
2327 {
2328     HCRYPTPROV prov;
2329     HCRYPTKEY key;
2330     BOOL result;
2331     DWORD keySpec, dataLen,dwParam;
2332     char szName[MAX_PATH];
2333
2334     result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2335     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2336      "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2337     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2338     ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2339      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2340     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2341      CRYPT_DELETEKEYSET);
2342     ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2343      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2344     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2345      CRYPT_DELETEKEYSET);
2346     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2347      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2348     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2349     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2350      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2351
2352     /* Delete the default container. */
2353     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2354     /* Once you've deleted the default container you can't open it as if it
2355      * already exists.
2356      */
2357     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2358     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2359      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2360     /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2361     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2362      CRYPT_VERIFYCONTEXT);
2363     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2364     if (!result) return;
2365     dataLen = sizeof(keySpec);
2366     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2367     if (result)
2368         ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2369          "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2370     /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2371      * supported, you can't get the keys from this container.
2372      */
2373     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2374     ok(!result && GetLastError() == NTE_NO_KEY,
2375      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2376     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2377     ok(!result && GetLastError() == NTE_NO_KEY,
2378      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2379     result = CryptReleaseContext(prov, 0);
2380     ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2381     /* You can create a new default container. */
2382     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2383      CRYPT_NEWKEYSET);
2384     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2385     /* But you still can't get the keys (until one's been generated.) */
2386     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2387     ok(!result && GetLastError() == NTE_NO_KEY,
2388      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2389     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2390     ok(!result && GetLastError() == NTE_NO_KEY,
2391      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2392     CryptReleaseContext(prov, 0);
2393     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2394
2395     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2396      CRYPT_DELETEKEYSET);
2397     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2398     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2399      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2400     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2401      CRYPT_VERIFYCONTEXT);
2402     ok(!result && GetLastError() == NTE_BAD_FLAGS,
2403      "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2404     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2405      CRYPT_NEWKEYSET);
2406     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2407     if (!result) return;
2408     /* Test provider parameters getter */
2409     dataLen = sizeof(dwParam);
2410     result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2411     ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2412         "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2413     dataLen = sizeof(dwParam);
2414     result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2415     ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2416         "Expected 0, got 0x%08X\n",dwParam);
2417     dataLen = sizeof(dwParam);
2418     result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2419     ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2420         "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2421     dataLen = sizeof(keySpec);
2422     SetLastError(0xdeadbeef);
2423     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2424     if (!result && GetLastError() == NTE_BAD_TYPE)
2425         skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2426     else
2427         ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2428             "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2429     /* PP_CONTAINER parameter */
2430     dataLen = sizeof(szName);
2431     result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2432     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2433         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2434         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2435     /* PP_UNIQUE_CONTAINER parameter */
2436     dataLen = sizeof(szName);
2437     SetLastError(0xdeadbeef);
2438     result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2439     if (!result && GetLastError() == NTE_BAD_TYPE)
2440     {
2441         skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2442     }
2443     else
2444     {
2445         char container[MAX_PATH];
2446
2447         ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2448         uniquecontainer(container);
2449         todo_wine
2450         {
2451             ok(dataLen == strlen(container)+1 ||
2452                broken(dataLen == strlen(szContainer)+1) /* WinME */,
2453                "Expected a param length of 70, got %d\n", dataLen);
2454             ok(!strcmp(container, szName) ||
2455                broken(!strcmp(szName, szContainer)) /* WinME */,
2456                "Wrong container name : %s\n", szName);
2457         }
2458     }
2459     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2460     ok(!result && GetLastError() == NTE_NO_KEY,
2461      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2462     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2463     ok(!result && GetLastError() == NTE_NO_KEY,
2464      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2465
2466     /* Importing a key exchange blob.. */
2467     result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2468      0, 0, &key);
2469     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2470     CryptDestroyKey(key);
2471     /* allows access to the key exchange key.. */
2472     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2473     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2474     CryptDestroyKey(key);
2475     /* but not to the private key. */
2476     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2477     ok(!result && GetLastError() == NTE_NO_KEY,
2478      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2479     CryptReleaseContext(prov, 0);
2480     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2481      CRYPT_DELETEKEYSET);
2482
2483     /* Whereas importing a sign blob.. */
2484     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2485      CRYPT_NEWKEYSET);
2486     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2487     if (!result) return;
2488     result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2489     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2490     CryptDestroyKey(key);
2491     /* doesn't allow access to the key exchange key.. */
2492     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2493     ok(!result && GetLastError() == NTE_NO_KEY,
2494      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2495     /* but does to the private key. */
2496     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2497     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2498     CryptDestroyKey(key);
2499     CryptReleaseContext(prov, 0);
2500
2501     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2502      CRYPT_DELETEKEYSET);
2503
2504     /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2505     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2506      CRYPT_NEWKEYSET);
2507     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2508     result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2509     ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2510     CryptDestroyKey(key);
2511     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2512     ok(!result, "expected CryptGetUserKey to fail\n");
2513     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2514     ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2515     CryptDestroyKey(key);
2516     CryptReleaseContext(prov, 0);
2517
2518     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2519      CRYPT_DELETEKEYSET);
2520
2521     /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2522     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2523      CRYPT_NEWKEYSET);
2524     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2525     result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2526     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2527     CryptDestroyKey(key);
2528     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2529     ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2530     CryptDestroyKey(key);
2531     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2532     ok(!result, "expected CryptGetUserKey to fail\n");
2533     CryptReleaseContext(prov, 0);
2534
2535     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2536      CRYPT_DELETEKEYSET);
2537
2538     /* test for the bug in accessing the user key in a container
2539      */
2540     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2541      CRYPT_NEWKEYSET);
2542     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2543     result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2544     ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2545     CryptDestroyKey(key);
2546     CryptReleaseContext(prov,0);
2547     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2548     ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2549     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2550     ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2551     CryptDestroyKey(key);
2552     CryptReleaseContext(prov, 0);
2553
2554     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2555      CRYPT_DELETEKEYSET);
2556
2557     /* test the machine key set */
2558     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2559      CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2560     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2561      CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2562     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2563     CryptReleaseContext(prov, 0);
2564     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2565      CRYPT_MACHINE_KEYSET);
2566     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2567     CryptReleaseContext(prov,0);
2568     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2569        CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2570     ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2571                 GetLastError());
2572     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2573      CRYPT_MACHINE_KEYSET);
2574     ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2575         "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2576
2577 }
2578
2579 static void test_key_permissions(void)
2580 {
2581     HCRYPTKEY hKey1, hKey2;
2582     DWORD dwVal, dwLen;
2583     BOOL result;
2584
2585     /* Create keys that are exportable */
2586     if (!init_base_environment(CRYPT_EXPORTABLE))
2587         return;
2588
2589     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2590     ok (result, "%08x\n", GetLastError());
2591     if (!result) return;
2592
2593     dwVal = 0xdeadbeef;
2594     dwLen = sizeof(DWORD);
2595     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2596     ok(result, "%08x\n", GetLastError());
2597     ok(dwVal ==
2598         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2599         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2600         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2601         " got %08x\n", dwVal);
2602
2603     /* The key exchange key's public key may be exported.. */
2604     result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2605     ok(result, "%08x\n", GetLastError());
2606     /* and its private key may be too. */
2607     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2608     ok(result, "%08x\n", GetLastError());
2609     /* Turning off the key's export permissions is "allowed".. */
2610     dwVal &= ~CRYPT_EXPORT;
2611     result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2612     ok(result ||
2613         broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2614         broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2615         "%08x\n", GetLastError());
2616     /* but it has no effect. */
2617     dwVal = 0xdeadbeef;
2618     dwLen = sizeof(DWORD);
2619     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2620     ok(result, "%08x\n", GetLastError());
2621     ok(dwVal ==
2622         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2623         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2624         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2625         " got %08x\n", dwVal);
2626     /* Thus, changing the export flag of the key doesn't affect whether the key
2627      * may be exported.
2628      */
2629     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2630     ok(result, "%08x\n", GetLastError());
2631
2632     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2633     ok (result, "%08x\n", GetLastError());
2634
2635     /* A subsequent get of the same key, into a different handle, also doesn't
2636      * show that the permissions have been changed.
2637      */
2638     dwVal = 0xdeadbeef;
2639     dwLen = sizeof(DWORD);
2640     result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2641     ok(result, "%08x\n", GetLastError());
2642     ok(dwVal ==
2643         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2644         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2645         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2646         " got %08x\n", dwVal);
2647
2648     CryptDestroyKey(hKey2);
2649     CryptDestroyKey(hKey1);
2650
2651     clean_up_base_environment();
2652 }
2653
2654 static void test_key_initialization(void)
2655 {
2656     DWORD dwLen;
2657     HCRYPTPROV prov1, prov2;
2658     HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2659     BOOL result;
2660     static BYTE abSessionKey[148] = {
2661         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2662         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2663         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2664         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2665         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2666         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2667         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2668         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2669         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2670         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2671         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2672         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2673         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2674         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2675         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2676         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2677         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2678         0x04, 0x8c, 0x49, 0x92
2679     };
2680
2681     /* Like init_base_environment, but doesn't generate new keys, as they'll
2682      * be imported instead.
2683      */
2684     if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2685     {
2686         result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2687                                      CRYPT_NEWKEYSET);
2688         ok(result, "%08x\n", GetLastError());
2689     }
2690     dwLen = (DWORD)sizeof(abPlainPrivateKey);
2691     result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2692
2693     dwLen = (DWORD)sizeof(abSessionKey);
2694     result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2695     ok(result, "%08x\n", GetLastError());
2696
2697     /* Once the key has been imported, subsequently acquiring a context with
2698      * the same name will allow retrieving the key.
2699      */
2700     result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2701     ok(result, "%08x\n", GetLastError());
2702     result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2703     ok(result, "%08x\n", GetLastError());
2704     if (result) CryptDestroyKey(hKey);
2705     CryptReleaseContext(prov2, 0);
2706
2707     CryptDestroyKey(hSessionKey);
2708     CryptDestroyKey(hKeyExchangeKey);
2709     CryptReleaseContext(prov1, 0);
2710     CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2711      CRYPT_DELETEKEYSET);
2712 }
2713
2714 START_TEST(rsaenh)
2715 {
2716     if (!init_base_environment(0))
2717         return;
2718     test_prov();
2719     test_gen_random();
2720     test_hashes();
2721     test_rc4();
2722     test_rc2();
2723     test_des();
2724     test_3des112();
2725     test_3des();
2726     test_hmac();
2727     test_mac();
2728     test_block_cipher_modes();
2729     test_import_private();
2730     test_verify_signature();
2731     test_rsa_encrypt();
2732     test_import_export();
2733     test_enum_container();
2734     clean_up_base_environment();
2735     test_key_permissions();
2736     test_key_initialization();
2737     test_schannel_provider();
2738     test_null_provider();
2739     test_rsa_round_trip();
2740     if (!init_aes_environment())
2741         return;
2742     test_aes(128);
2743     test_aes(192);
2744     test_aes(256);
2745     test_sha2();
2746     clean_up_aes_environment();
2747 }