rsaenh: Don't return salt for algorithms that don't support it.
[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     ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == ERROR_NO_TOKEN /* Win7 */),
748        "expected NTE_BAD_KEY or ERROR_NO_TOKEN, got %08x\n", GetLastError());
749
750     dwLen = 13;
751     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
752     ok(result, "%08x\n", GetLastError());
753
754     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
755     ok(result, "%08x\n", GetLastError());
756
757     for (i=0; i<4; i++)
758     {
759       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
760
761       dwLen = cTestData[i].enclen;
762       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
763       ok(result, "%08x\n", GetLastError());
764       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
765
766       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
767       ok(result, "%08x\n", GetLastError());
768       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
769       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
770       if((dwLen != cTestData[i].enclen) ||
771          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
772       {
773           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
774           printBytes("got",pbData,dwLen);
775       }
776     }
777     result = CryptDestroyKey(hKey);
778     ok(result, "%08x\n", GetLastError());
779 }
780
781 static void test_sha2(void)
782 {
783     static const unsigned char sha256hash[32] = {
784         0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
785         0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
786         0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
787         0x1a, 0x08
788     };
789     static const unsigned char sha384hash[48] = {
790         0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
791         0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
792         0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
793         0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
794         0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
795     };
796     static const unsigned char sha512hash[64] = {
797         0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
798         0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
799         0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
800         0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
801         0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
802         0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
803         0xb7, 0xf4, 0x81, 0xd4
804     };
805     unsigned char pbData[2048];
806     BOOL result;
807     HCRYPTHASH hHash;
808     BYTE pbHashValue[64];
809     DWORD hashlen, len;
810     int i;
811
812     for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
813
814     /* SHA-256 hash */
815     SetLastError(0xdeadbeef);
816     result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
817     if (!result && GetLastError() == NTE_BAD_ALGID) {
818         win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
819         return;
820     }
821     ok(result, "%08x\n", GetLastError());
822     if (result) {
823         len = sizeof(DWORD);
824         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
825         ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
826
827         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
828         ok(result, "%08x\n", GetLastError());
829
830         len = 32;
831         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
832         ok(result, "%08x\n", GetLastError());
833
834         ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
835
836         result = CryptDestroyHash(hHash);
837         ok(result, "%08x\n", GetLastError());
838     }
839
840     /* SHA-384 hash */
841     result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
842     ok(result, "%08x\n", GetLastError());
843     if (result) {
844         len = sizeof(DWORD);
845         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
846         ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
847
848         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
849         ok(result, "%08x\n", GetLastError());
850
851         len = 48;
852         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
853         ok(result, "%08x\n", GetLastError());
854
855         ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
856
857         result = CryptDestroyHash(hHash);
858         ok(result, "%08x\n", GetLastError());
859     }
860
861     /* SHA-512 hash */
862     result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
863     ok(result, "%08x\n", GetLastError());
864     if (result) {
865         len = sizeof(DWORD);
866         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
867         ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
868
869         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
870         ok(result, "%08x\n", GetLastError());
871
872         len = 64;
873         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
874         ok(result, "%08x\n", GetLastError());
875
876         ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
877
878         result = CryptDestroyHash(hHash);
879         ok(result, "%08x\n", GetLastError());
880     }
881 }
882
883 static void test_rc2(void)
884 {
885     static const BYTE rc2_40_encrypted[16] = {
886         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
887         0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
888     static const BYTE rc2_128_encrypted[] = {
889         0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
890         0xb6,0x66 };
891     HCRYPTHASH hHash;
892     HCRYPTKEY hKey;
893     BOOL result;
894     DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
895     BYTE *pbTemp;
896     unsigned char pbData[2000], pbHashValue[16];
897     int i;
898     
899     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
900
901     /* MD2 Hashing */
902     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
903     if (!result) {
904         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
905     } else {
906         CRYPT_INTEGER_BLOB salt;
907
908         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
909         ok(result, "%08x\n", GetLastError());
910
911         dwLen = 16;
912         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
913         ok(result, "%08x\n", GetLastError());
914
915         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
916         ok(result, "%08x\n", GetLastError());
917
918         dwLen = sizeof(DWORD);
919         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
920         ok(result, "%08x\n", GetLastError());
921
922         dwMode = CRYPT_MODE_CBC;
923         result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
924         ok(result, "%08x\n", GetLastError());
925
926         dwLen = sizeof(DWORD);
927         result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
928         ok(result, "%08x\n", GetLastError());
929
930         dwModeBits = 0xdeadbeef;
931         dwLen = sizeof(DWORD);
932         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
933         ok(result, "%08x\n", GetLastError());
934         ok(dwModeBits ==
935             (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
936             broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
937             "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
938             " got %08x\n", dwModeBits);
939
940         dwLen = sizeof(DWORD);
941         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
942         ok(result, "%08x\n", GetLastError());
943
944         dwLen = sizeof(DWORD);
945         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
946         ok(result, "%08x\n", GetLastError());
947
948         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
949         ok(result, "%08x\n", GetLastError());
950         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
951         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
952         HeapFree(GetProcessHeap(), 0, pbTemp);
953
954         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
955         ok(result, "%08x\n", GetLastError());
956         /* The default salt length is always 11... */
957         ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
958         /* and the default salt is always empty. */
959         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
960         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
961         for (i=0; i<dwLen; i++)
962             ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
963         HeapFree(GetProcessHeap(), 0, pbTemp);
964
965         dwLen = sizeof(DWORD);
966         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
967
968         result = CryptDestroyHash(hHash);
969         ok(result, "%08x\n", GetLastError());
970
971         dwDataLen = 13;
972         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
973         ok(result, "%08x\n", GetLastError());
974
975         ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
976
977         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
978         ok(result, "%08x\n", GetLastError());
979         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
980         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
981         HeapFree(GetProcessHeap(), 0, pbTemp);
982
983         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
984         ok(result, "%08x\n", GetLastError());
985
986         /* Setting the salt also succeeds... */
987         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
988         ok(result, "setting salt failed: %08x\n", GetLastError());
989         /* but the resulting salt length is now zero? */
990         dwLen = 0;
991         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
992         ok(result, "%08x\n", GetLastError());
993         ok(dwLen == 0, "unexpected salt length %d\n", dwLen);
994         /* What sizes salt can I set? */
995         salt.pbData = pbData;
996         for (i=0; i<24; i++)
997         {
998             salt.cbData = i;
999             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1000             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1001             /* The returned salt length is the same as the set salt length */
1002             result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1003             ok(result, "%08x\n", GetLastError());
1004             ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1005         }
1006         salt.cbData = 25;
1007         SetLastError(0xdeadbeef);
1008         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1009         ok(!result ||
1010            broken(result), /* Win9x, WinMe, NT4, W2K */
1011            "%08x\n", GetLastError());
1012
1013         result = CryptDestroyKey(hKey);
1014         ok(result, "%08x\n", GetLastError());
1015     }
1016
1017     /* Again, but test setting the effective key len */
1018     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1019
1020     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1021     if (!result) {
1022         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1023     } else {
1024         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1025         ok(result, "%08x\n", GetLastError());
1026
1027         dwLen = 16;
1028         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1029         ok(result, "%08x\n", GetLastError());
1030
1031         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1032         ok(result, "%08x\n", GetLastError());
1033
1034         SetLastError(0xdeadbeef);
1035         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1036         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1037         dwKeyLen = 0;
1038         SetLastError(0xdeadbeef);
1039         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1040         ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1041         dwKeyLen = 1025;
1042         SetLastError(0xdeadbeef);
1043         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1044
1045         dwLen = sizeof(dwKeyLen);
1046         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1047         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1048         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1049         ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1050
1051         dwKeyLen = 128;
1052         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1053         ok(result, "%d\n", GetLastError());
1054
1055         dwLen = sizeof(dwKeyLen);
1056         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1057         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1058         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1059         ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1060
1061         result = CryptDestroyHash(hHash);
1062         ok(result, "%08x\n", GetLastError());
1063
1064         dwDataLen = 13;
1065         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1066         ok(result, "%08x\n", GetLastError());
1067
1068         ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1069                 "RC2 encryption failed!\n");
1070
1071         /* Oddly enough this succeeds, though it should have no effect */
1072         dwKeyLen = 40;
1073         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1074         ok(result, "%d\n", GetLastError());
1075
1076         result = CryptDestroyKey(hKey);
1077         ok(result, "%08x\n", GetLastError());
1078     }
1079 }
1080
1081 static void test_rc4(void)
1082 {
1083     static const BYTE rc4[16] = { 
1084         0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0, 
1085         0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };    
1086     BOOL result;
1087     HCRYPTHASH hHash;
1088     HCRYPTKEY hKey;
1089     DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1090     unsigned char pbData[2000], *pbTemp;
1091     unsigned char pszBuffer[256];
1092     int i;
1093
1094     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1095
1096     /* MD2 Hashing */
1097     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1098     if (!result) {
1099         /* rsaenh compiled without OpenSSL */
1100         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1101     } else {
1102         CRYPT_INTEGER_BLOB salt;
1103
1104         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1105            ok(result, "%08x\n", GetLastError());
1106
1107         dwLen = 16;
1108         result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1109         ok(result, "%08x\n", GetLastError());
1110
1111         result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1112         ok(result, "%08x\n", GetLastError());
1113
1114         dwLen = sizeof(DWORD);
1115         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1116         ok(result, "%08x\n", GetLastError());
1117
1118         dwLen = sizeof(DWORD);
1119         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1120         ok(result, "%08x\n", GetLastError());
1121
1122         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1123         ok(result, "%08x\n", GetLastError());
1124         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1125         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1126         HeapFree(GetProcessHeap(), 0, pbTemp);
1127
1128         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1129         ok(result, "%08x\n", GetLastError());
1130         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1131         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1132         HeapFree(GetProcessHeap(), 0, pbTemp);
1133
1134         dwLen = sizeof(DWORD);
1135         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1136
1137         result = CryptDestroyHash(hHash);
1138         ok(result, "%08x\n", GetLastError());
1139
1140         dwDataLen = 16;
1141         result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1142         ok(result, "%08x\n", GetLastError());
1143         dwDataLen = 16;
1144         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1145         ok(result, "%08x\n", GetLastError());
1146
1147         ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1148
1149         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1150         ok(result, "%08x\n", GetLastError());
1151
1152         /* Setting the salt also succeeds... */
1153         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1154         ok(result, "setting salt failed: %08x\n", GetLastError());
1155         /* but the resulting salt length is now zero? */
1156         dwLen = 0;
1157         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1158         ok(result, "%08x\n", GetLastError());
1159         ok(dwLen == 0, "unexpected salt length %d\n", dwLen);
1160         /* What sizes salt can I set? */
1161         salt.pbData = pbData;
1162         for (i=0; i<24; i++)
1163         {
1164             salt.cbData = i;
1165             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1166             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1167             /* The returned salt length is the same as the set salt length */
1168             result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1169             ok(result, "%08x\n", GetLastError());
1170             ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1171         }
1172         salt.cbData = 25;
1173         SetLastError(0xdeadbeef);
1174         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1175         ok(!result ||
1176            broken(result), /* Win9x, WinMe, NT4, W2K */
1177            "%08x\n", GetLastError());
1178
1179         result = CryptDestroyKey(hKey);
1180         ok(result, "%08x\n", GetLastError());
1181     }
1182 }
1183
1184 static void test_hmac(void) {
1185     HCRYPTKEY hKey;
1186     HCRYPTHASH hHash;
1187     BOOL result;
1188     /* Using CALG_MD2 here fails on Windows 2003, why ? */
1189     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1190     DWORD dwLen;
1191     BYTE abData[256];
1192     static const BYTE hmac[16] = { 
1193         0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c, 
1194         0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1195     int i;
1196
1197     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1198
1199     if (!derive_key(CALG_RC2, &hKey, 56)) return;
1200
1201     result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1202     ok(result, "%08x\n", GetLastError());
1203     if (!result) return;
1204
1205     result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1206     ok(result, "%08x\n", GetLastError());
1207
1208     result = CryptHashData(hHash, abData, sizeof(abData), 0);
1209     ok(result, "%08x\n", GetLastError());
1210
1211     dwLen = sizeof(abData)/sizeof(BYTE);
1212     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1213     ok(result, "%08x\n", GetLastError());
1214
1215     ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1216     
1217     result = CryptDestroyHash(hHash);
1218     ok(result, "%08x\n", GetLastError());
1219     
1220     result = CryptDestroyKey(hKey);
1221     ok(result, "%08x\n", GetLastError());
1222
1223     /* Provoke errors */
1224     result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1225     ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1226 }
1227
1228 static void test_mac(void) {
1229     HCRYPTKEY hKey;
1230     HCRYPTHASH hHash;
1231     BOOL result;
1232     DWORD dwLen;
1233     BYTE abData[256], abEnc[264];
1234     static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1235     int i;
1236
1237     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1238     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1239
1240     if (!derive_key(CALG_RC2, &hKey, 40)) return;
1241
1242     dwLen = 256;
1243     result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1244     ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1245     
1246     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1247     ok(result, "%08x\n", GetLastError());
1248     if (!result) return;
1249
1250     result = CryptHashData(hHash, abData, sizeof(abData), 0);
1251     ok(result, "%08x\n", GetLastError());
1252
1253     dwLen = sizeof(abData)/sizeof(BYTE);
1254     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1255     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1256
1257     ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1258     
1259     result = CryptDestroyHash(hHash);
1260     ok(result, "%08x\n", GetLastError());
1261     
1262     result = CryptDestroyKey(hKey);
1263     ok(result, "%08x\n", GetLastError());
1264     
1265     /* Provoke errors */
1266     if (!derive_key(CALG_RC4, &hKey, 56)) return;
1267
1268     SetLastError(0xdeadbeef);
1269     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1270     ok((!result && GetLastError() == NTE_BAD_KEY) ||
1271             broken(result), /* Win9x, WinMe, NT4, W2K */
1272             "%08x\n", GetLastError());
1273
1274     result = CryptDestroyKey(hKey);
1275     ok(result, "%08x\n", GetLastError());
1276 }
1277
1278 static BYTE abPlainPrivateKey[596] = {
1279     0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1280     0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1281     0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1282     0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1283     0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1284     0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1285     0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1286     0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1287     0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1288     0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1289     0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1290     0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1291     0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1292     0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1293     0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1294     0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1295     0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1296     0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1297     0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1298     0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1299     0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1300     0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1301     0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1302     0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1303     0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1304     0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1305     0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1306     0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1307     0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1308     0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1309     0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1310     0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1311     0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1312     0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1313     0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1314     0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1315     0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1316     0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1317     0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1318     0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1319     0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1320     0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1321     0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1322     0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1323     0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1324     0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1325     0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1326     0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1327     0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1328     0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1329     0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1330     0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1331     0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1332     0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1333     0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1334     0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1335     0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1336     0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1337     0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1338     0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1339     0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1340     0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1341     0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1342     0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1343     0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1344     0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1345     0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1346     0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1347     0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1348     0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1349     0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1350     0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1351     0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1352     0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1353     0xf2, 0x5d, 0x58, 0x07
1354 };
1355
1356 static void test_import_private(void) 
1357 {
1358     DWORD dwLen, dwVal;
1359     HCRYPTKEY hKeyExchangeKey, hSessionKey;
1360     BOOL result;
1361     static BYTE abSessionKey[148] = {
1362         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1363         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1364         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1365         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1366         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1367         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1368         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1369         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1370         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1371         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1372         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1373         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1374         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1375         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1376         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1377         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1378         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1379         0x04, 0x8c, 0x49, 0x92
1380     };
1381     static BYTE abEncryptedMessage[12] = {
1382         0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1383         0x1c, 0xfd, 0xde, 0x71
1384     };
1385             
1386     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1387     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1388     if (!result) {
1389         /* rsaenh compiled without OpenSSL */
1390         ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1391         return;
1392     }
1393
1394     dwLen = (DWORD)sizeof(abSessionKey);
1395     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1396     ok(result, "%08x\n", GetLastError());
1397     if (!result) return;
1398
1399     dwVal = 0xdeadbeef;
1400     dwLen = sizeof(DWORD);
1401     result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1402     ok(result, "%08x\n", GetLastError());
1403     ok(dwVal ==
1404         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1405         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1406         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1407         " got %08x\n", dwVal);
1408
1409     dwLen = (DWORD)sizeof(abEncryptedMessage);
1410     result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1411     ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12), 
1412        "%08x, len: %d\n", GetLastError(), dwLen);
1413     CryptDestroyKey(hSessionKey);
1414     
1415     if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1416
1417     dwLen = (DWORD)sizeof(abSessionKey);
1418     result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1419     ok(result, "%08x\n", GetLastError());
1420     CryptDestroyKey(hSessionKey);
1421     if (!result) return;
1422
1423     dwLen = (DWORD)sizeof(abSessionKey);
1424     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1425     ok(result, "%08x\n", GetLastError());
1426     if (!result) return;
1427
1428     CryptDestroyKey(hSessionKey);
1429     CryptDestroyKey(hKeyExchangeKey);
1430 }
1431
1432 static void test_verify_signature(void) {
1433     HCRYPTHASH hHash;
1434     HCRYPTKEY hPubSignKey;
1435     BYTE abData[] = "Wine rocks!";
1436     BOOL result;
1437     BYTE abPubKey[148] = {
1438         0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 
1439         0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 
1440         0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19, 
1441         0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27, 
1442         0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8, 
1443         0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda, 
1444         0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a, 
1445         0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc, 
1446         0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c, 
1447         0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c, 
1448         0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89, 
1449         0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b, 
1450         0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa, 
1451         0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63, 
1452         0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff, 
1453         0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49, 
1454         0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87, 
1455         0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7, 
1456         0xe1, 0x21, 0x50, 0xac
1457     };
1458     /* md2 with hash oid */
1459     BYTE abSignatureMD2[128] = {
1460         0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67, 
1461         0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b, 
1462         0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda, 
1463         0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59, 
1464         0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a, 
1465         0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34, 
1466         0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40, 
1467         0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7, 
1468         0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0, 
1469         0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06, 
1470         0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51, 
1471         0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f, 
1472         0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46, 
1473         0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25, 
1474         0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0, 
1475         0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1476     };
1477     /* md2 without hash oid */
1478     BYTE abSignatureMD2NoOID[128] = {
1479         0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d, 
1480         0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19, 
1481         0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd, 
1482         0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4, 
1483         0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65, 
1484         0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99, 
1485         0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf, 
1486         0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc, 
1487         0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0, 
1488         0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01, 
1489         0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7, 
1490         0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f, 
1491         0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a, 
1492         0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9, 
1493         0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06, 
1494         0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1495     };
1496     /* md4 with hash oid */
1497     BYTE abSignatureMD4[128] = {
1498         0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51, 
1499         0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b, 
1500         0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2, 
1501         0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e, 
1502         0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13, 
1503         0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9, 
1504         0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f, 
1505         0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96, 
1506         0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9, 
1507         0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e, 
1508         0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0, 
1509         0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe, 
1510         0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18, 
1511         0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab, 
1512         0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3, 
1513         0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1514     };
1515     /* md4 without hash oid */
1516     BYTE abSignatureMD4NoOID[128] = {
1517         0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda, 
1518         0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24, 
1519         0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0, 
1520         0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36, 
1521         0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85, 
1522         0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3, 
1523         0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f, 
1524         0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9, 
1525         0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06, 
1526         0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f, 
1527         0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb, 
1528         0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96, 
1529         0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f, 
1530         0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9, 
1531         0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb, 
1532         0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1533     }; 
1534     /* md5 with hash oid */
1535     BYTE abSignatureMD5[128] = {
1536         0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5, 
1537         0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f, 
1538         0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7, 
1539         0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98, 
1540         0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec, 
1541         0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5, 
1542         0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04, 
1543         0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b, 
1544         0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95, 
1545         0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c, 
1546         0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29, 
1547         0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9, 
1548         0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c, 
1549         0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90, 
1550         0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e, 
1551         0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1552     };
1553     /* md5 without hash oid */
1554     BYTE abSignatureMD5NoOID[128] = {
1555         0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f, 
1556         0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75, 
1557         0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f, 
1558         0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d, 
1559         0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f, 
1560         0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49, 
1561         0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8, 
1562         0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c, 
1563         0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23, 
1564         0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19, 
1565         0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb, 
1566         0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3, 
1567         0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b, 
1568         0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b, 
1569         0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5, 
1570         0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1571     };
1572     /* sha with hash oid */
1573     BYTE abSignatureSHA[128] = {
1574         0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91, 
1575         0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd, 
1576         0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24, 
1577         0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94, 
1578         0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f, 
1579         0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a, 
1580         0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52, 
1581         0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20, 
1582         0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5, 
1583         0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a, 
1584         0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff, 
1585         0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53, 
1586         0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00, 
1587         0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e, 
1588         0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98, 
1589         0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1590     };
1591     /* sha without hash oid */
1592     BYTE abSignatureSHANoOID[128] = {
1593         0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6, 
1594         0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a, 
1595         0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f, 
1596         0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37, 
1597         0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65, 
1598         0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe, 
1599         0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6, 
1600         0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe, 
1601         0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c, 
1602         0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4, 
1603         0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80, 
1604         0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a, 
1605         0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00, 
1606         0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd, 
1607         0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67, 
1608         0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1609     }; 
1610     
1611     result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1612     ok(result, "%08x\n", GetLastError());
1613     if (!result) return;
1614
1615     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1616     ok(result, "%08x\n", GetLastError());
1617     if (!result) return;
1618
1619     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1620     ok(result, "%08x\n", GetLastError());
1621     if (!result) return;
1622
1623     /*check that a NULL pointer signature is correctly handled*/
1624     result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1625     ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1626      "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1627     if (result) return;
1628
1629     /* check that we get a bad signature error when the signature is too short*/
1630     SetLastError(0xdeadbeef);
1631     result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1632     ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1633      broken(result), /* Win9x, WinMe, NT4 */
1634      "Expected NTE_BAD_SIGNATURE, got %08x\n",  GetLastError());
1635
1636     result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1637     ok(result, "%08x\n", GetLastError());
1638     if (!result) return;
1639
1640     result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1641     ok(result, "%08x\n", GetLastError());
1642     if (!result) return;
1643
1644     /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about 
1645      * the OID at all. */
1646     /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1647     ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1648     if (result) return;*/
1649
1650     CryptDestroyHash(hHash);
1651
1652     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1653     ok(result, "%08x\n", GetLastError());
1654     if (!result) return;
1655
1656     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1657     ok(result, "%08x\n", GetLastError());
1658     if (!result) return;
1659
1660     result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1661     ok(result, "%08x\n", GetLastError());
1662     if (!result) return;
1663
1664     result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1665     ok(result, "%08x\n", GetLastError());
1666     if (!result) return;
1667
1668     CryptDestroyHash(hHash);
1669
1670     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1671     ok(result, "%08x\n", GetLastError());
1672     if (!result) return;
1673
1674     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1675     ok(result, "%08x\n", GetLastError());
1676     if (!result) return;
1677
1678     result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1679     ok(result, "%08x\n", GetLastError());
1680     if (!result) return;
1681
1682     result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1683     ok(result, "%08x\n", GetLastError());
1684     if (!result) return;
1685
1686     CryptDestroyHash(hHash);
1687
1688     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1689     ok(result, "%08x\n", GetLastError());
1690     if (!result) return;
1691
1692     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1693     ok(result, "%08x\n", GetLastError());
1694     if (!result) return;
1695
1696     result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1697     ok(result, "%08x\n", GetLastError());
1698     if (!result) return;
1699
1700     result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1701     ok(result, "%08x\n", GetLastError());
1702     if (!result) return;
1703
1704     CryptDestroyHash(hHash);
1705     CryptDestroyKey(hPubSignKey);
1706 }
1707
1708 static void test_rsa_encrypt(void)
1709 {
1710     HCRYPTKEY hRSAKey;
1711     BYTE abData[2048] = "Wine rocks!";
1712     BOOL result;
1713     DWORD dwVal, dwLen;
1714
1715     /* It is allowed to use the key exchange key for encryption/decryption */
1716     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1717     ok (result, "%08x\n", GetLastError());
1718     if (!result) return;
1719
1720     dwLen = 12;
1721     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1722     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1723     ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1724     dwLen = 12;
1725     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1726     ok (result, "%08x\n", GetLastError());
1727     if (!result) return;
1728
1729     result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1730     ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1731     
1732     dwVal = 0xdeadbeef;
1733     dwLen = sizeof(DWORD);
1734     result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1735     ok(result, "%08x\n", GetLastError());
1736     ok(dwVal ==
1737         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1738         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1739         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1740         " got %08x\n", dwVal);
1741
1742     /* An RSA key doesn't support salt */
1743     result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1744     ok(!result && GetLastError() == NTE_BAD_KEY,
1745        "expected NTE_BAD_KEY, got %08x\n", GetLastError());
1746
1747     /* The key exchange key's public key may be exported.. */
1748     result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1749     ok(result, "%08x\n", GetLastError());
1750     /* but its private key may not be. */
1751     SetLastError(0xdeadbeef);
1752     result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1753     ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1754         broken(result), /* Win9x/NT4 */
1755         "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1756     /* Setting the permissions of the key exchange key isn't allowed, either. */
1757     dwVal |= CRYPT_EXPORT;
1758     SetLastError(0xdeadbeef);
1759     result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1760     ok(!result &&
1761         (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1762         "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1763
1764     CryptDestroyKey(hRSAKey);
1765
1766     /* It is not allowed to use the signature key for encryption/decryption */
1767     result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1768     ok (result, "%08x\n", GetLastError());
1769     if (!result) return;
1770
1771     dwVal = 0xdeadbeef;
1772     dwLen = sizeof(DWORD);
1773     result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1774     ok(result, "%08x\n", GetLastError());
1775     ok(dwVal ==
1776         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1777         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1778         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1779         " got %08x\n", dwVal);
1780
1781     /* The signature key's public key may also be exported.. */
1782     result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1783     ok(result, "%08x\n", GetLastError());
1784     /* but its private key may not be. */
1785     SetLastError(0xdeadbeef);
1786     result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1787     ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1788         broken(result), /* Win9x/NT4 */
1789         "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1790     /* Setting the permissions of the signature key isn't allowed, either. */
1791     dwVal |= CRYPT_EXPORT;
1792     SetLastError(0xdeadbeef);
1793     result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1794     ok(!result &&
1795         (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1796         "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1797
1798     dwLen = 12;
1799     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1800     ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1801
1802     CryptDestroyKey(hRSAKey);
1803 }
1804
1805 static void test_import_export(void)
1806 {
1807     DWORD dwLen, dwDataLen, dwVal;
1808     HCRYPTKEY hPublicKey, hPrivKey;
1809     BOOL result;
1810     ALG_ID algID;
1811     BYTE emptyKey[2048], *exported_key;
1812     static BYTE abPlainPublicKey[84] = {
1813         0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1814         0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1815         0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1816         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1817         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1818         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1819         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1820         0x11, 0x11, 0x11, 0x11, 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
1824     };
1825     static BYTE priv_key_with_high_bit[] = {
1826         0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1827         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1828         0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1829         0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1830         0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1831         0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1832         0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1833         0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1834         0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1835         0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1836         0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1837         0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1838         0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1839         0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1840         0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1841         0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1842         0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1843         0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1844         0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1845         0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1846         0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1847         0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1848         0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1849         0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1850         0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1851         0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1852         0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1853         0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1854         0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1855         0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1856         0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1857         0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1858         0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1859         0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1860         0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1861         0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1862         0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1863         0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1864         0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1865         0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1866         0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1867         0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1868         0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1869         0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1870         0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1871         0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1872         0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1873         0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1874         0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1875         0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1876         0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1877         0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1878         0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1879         0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1880         0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1881         0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1882         0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1883         0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1884         0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1885         0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1886         0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1887         0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1888         0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1889         0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1890         0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1891         0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1892         0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1893         0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1894         0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1895         0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1896         0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1897         0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1898         0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1899         0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1900         0xb6, 0x5f, 0x01, 0x5e
1901     };
1902     static const BYTE expected_exported_priv_key[] = {
1903         0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1904         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1905         0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1906         0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1907         0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1908         0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1909         0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1910         0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1911         0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1912         0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1913         0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1914         0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1915         0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1916         0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1917         0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1918         0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1919         0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1920         0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1921         0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1922         0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1923         0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1924         0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1925         0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1926         0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1927         0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1928         0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1929         0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1930         0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1931         0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1932         0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1933         0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1934         0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1935         0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1936         0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1937         0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1938         0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1939         0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1940         0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1941         0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1942         0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1943         0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1944         0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1945         0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1946         0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1947         0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
1948         0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
1949         0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
1950         0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
1951         0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
1952         0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
1953         0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
1954         0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
1955         0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
1956         0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
1957         0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
1958         0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
1959         0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
1960         0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
1961         0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
1962         0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
1963         0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
1964         0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
1965         0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
1966         0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
1967         0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
1968         0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
1969         0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
1970         0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
1971         0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
1972         0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
1973         0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
1974         0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
1975         0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
1976         0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
1977         0xb6, 0x5f, 0x01, 0x5e
1978     };
1979
1980     dwLen=84;
1981     result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1982     ok(result, "failed to import the public key\n");
1983
1984     dwDataLen=sizeof(algID);
1985     result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1986     ok(result, "failed to get the KP_ALGID from the imported public key\n");
1987     ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1988         
1989     dwVal = 0xdeadbeef;
1990     dwDataLen = sizeof(DWORD);
1991     result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
1992     ok(result, "%08x\n", GetLastError());
1993     ok(dwVal ==
1994         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1995         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1996         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1997         " got %08x\n", dwVal);
1998     result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1999     ok(result, "failed to export the fresh imported public key\n");
2000     ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2001     ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2002
2003     CryptDestroyKey(hPublicKey);
2004
2005     result = CryptImportKey(hProv, priv_key_with_high_bit,
2006         sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2007     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2008
2009     result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2010     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2011     exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2012     result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2013         &dwDataLen);
2014     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2015
2016     ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2017         dwDataLen);
2018     ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2019         "unexpected value\n");
2020
2021     HeapFree(GetProcessHeap(), 0, exported_key);
2022
2023     CryptDestroyKey(hPrivKey);
2024 }
2025         
2026 static void test_schannel_provider(void)
2027 {
2028     HCRYPTPROV hProv;
2029     HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2030     HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2031     BOOL result;
2032     DWORD dwLen;
2033     SCHANNEL_ALG saSChannelAlg;
2034     CRYPT_DATA_BLOB data_blob;
2035     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2036     BYTE abTLS1Master[140] = {
2037         0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00, 
2038         0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68, 
2039         0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97, 
2040         0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53, 
2041         0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24, 
2042         0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3, 
2043         0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8, 
2044         0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d, 
2045         0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e, 
2046         0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e, 
2047         0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40, 
2048         0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b, 
2049         0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb, 
2050         0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6, 
2051         0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac, 
2052         0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41, 
2053         0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4, 
2054         0xd3, 0x1e, 0x82, 0xb3
2055     };
2056     BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2057     BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2058     BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2059     BYTE abClientFinished[16] = "client finished";
2060     BYTE abData[16] = "Wine rocks!";
2061     BYTE abMD5Hash[16];
2062     static const BYTE abEncryptedData[16] = {
2063         0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2064         0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d    
2065     };
2066     static const BYTE abPRF[16] = {
2067         0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2068         0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2069     };
2070     static const BYTE abMD5[16] = {
2071         0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2072         0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2073     };
2074     
2075     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2076     if (!result)
2077     {
2078         win_skip("no PROV_RSA_SCHANNEL support\n");
2079         return;
2080     }
2081     ok (result, "%08x\n", GetLastError());
2082     if (result)
2083         CryptReleaseContext(hProv, 0);
2084
2085     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2086     ok (result, "%08x\n", GetLastError());
2087     if (!result) return;
2088     
2089     /* To get deterministic results, we import the TLS1 master secret (which
2090      * is typically generated from a random generator). Therefore, we need
2091      * an RSA key. */
2092     dwLen = (DWORD)sizeof(abPlainPrivateKey);
2093     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2094     ok (result, "%08x\n", GetLastError());
2095     if (!result) return;
2096
2097     dwLen = (DWORD)sizeof(abTLS1Master);
2098     result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2099     ok (result, "%08x\n", GetLastError());
2100     if (!result) return;    
2101    
2102     /* Setting the TLS1 client and server random parameters, as well as the 
2103      * MAC and encryption algorithm parameters. */
2104     data_blob.cbData = 33;
2105     data_blob.pbData = abClientSecret;
2106     result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2107     ok (result, "%08x\n", GetLastError());
2108     if (!result) return;
2109
2110     data_blob.cbData = 33;
2111     data_blob.pbData = abServerSecret;
2112     result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2113     ok (result, "%08x\n", GetLastError());
2114     if (!result) return;
2115     
2116     saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2117     saSChannelAlg.Algid = CALG_DES;
2118     saSChannelAlg.cBits = 64;
2119     saSChannelAlg.dwFlags = 0;
2120     saSChannelAlg.dwReserved = 0;
2121     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2122     ok (result, "%08x\n", GetLastError());
2123     if (!result) return;
2124
2125     saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2126     saSChannelAlg.Algid = CALG_MD5;
2127     saSChannelAlg.cBits = 128;
2128     saSChannelAlg.dwFlags = 0;
2129     saSChannelAlg.dwReserved = 0;
2130     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2131     ok (result, "%08x\n", GetLastError());
2132     if (!result) return;
2133
2134     /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2135      * (Keys can only be derived from hashes, not from other keys.) */
2136     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2137     ok (result, "%08x\n", GetLastError());
2138     if (!result) return;
2139
2140     /* Deriving the server write encryption key from the master hash */
2141     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2142     ok (result, "%08x\n", GetLastError());
2143     if (!result) return;
2144
2145     /* Encrypting some data with the server write encryption key and checking the result. */
2146     dwLen = 12;
2147     result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2148     ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2149
2150     /* Second test case: Test the TLS1 pseudo random number function. */
2151     result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2152     ok (result, "%08x\n", GetLastError());
2153     if (!result) return;
2154
2155     /* Set the label and seed parameters for the random number function */
2156     data_blob.cbData = 36;
2157     data_blob.pbData = abHashedHandshakes;
2158     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2159     ok (result, "%08x\n", GetLastError());
2160     if (!result) return;
2161
2162     data_blob.cbData = 15;
2163     data_blob.pbData = abClientFinished;
2164     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2165     ok (result, "%08x\n", GetLastError());
2166     if (!result) return;
2167
2168     /* Generate some pseudo random bytes and check if they are correct. */
2169     dwLen = (DWORD)sizeof(abData);
2170     result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2171     ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)), 
2172         "%08x\n", GetLastError());
2173
2174     /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2175      * Hash some data with the HMAC. Compare results. */
2176     result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2177     ok (result, "%08x\n", GetLastError());
2178     if (!result) return;
2179     
2180     result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2181     ok (result, "%08x\n", GetLastError());
2182     if (!result) return;
2183
2184     result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2185     ok (result, "%08x\n", GetLastError());
2186     if (!result) return;
2187
2188     result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2189     ok (result, "%08x\n", GetLastError());
2190     if (!result) return;
2191
2192     dwLen = (DWORD)sizeof(abMD5Hash);
2193     result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2194     ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2195
2196     CryptDestroyHash(hHMAC);
2197     CryptDestroyHash(hTLS1PRF);
2198     CryptDestroyHash(hMasterHash);
2199     CryptDestroyKey(hServerWriteMACKey);
2200     CryptDestroyKey(hServerWriteKey);
2201     CryptDestroyKey(hRSAKey);
2202     CryptDestroyKey(hMasterSecret);
2203     CryptReleaseContext(hProv, 0);
2204     CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2205 }
2206
2207 /* Test that a key can be used to encrypt data and exported, and that, when
2208  * the exported key is imported again, can be used to decrypt the original
2209  * data again.
2210  */
2211 static void test_rsa_round_trip(void)
2212 {
2213     static const char test_string[] = "Well this is a fine how-do-you-do.";
2214     HCRYPTPROV prov;
2215     HCRYPTKEY signKey, keyExchangeKey;
2216     BOOL result;
2217     BYTE data[256], *exportedKey;
2218     DWORD dataLen, keyLen;
2219
2220     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2221      CRYPT_DELETEKEYSET);
2222
2223     /* Generate a new key... */
2224     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2225      CRYPT_NEWKEYSET);
2226     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2227     result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2228     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2229     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2230     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2231     /* encrypt some data with it... */
2232     memcpy(data, test_string, strlen(test_string) + 1);
2233     dataLen = strlen(test_string) + 1;
2234     result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2235                           sizeof(data));
2236     ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2237        "CryptEncrypt failed: %08x\n", GetLastError());
2238     /* export the key... */
2239     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2240                             &keyLen);
2241     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2242     exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2243     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2244                             &keyLen);
2245     /* destroy the key... */
2246     CryptDestroyKey(keyExchangeKey);
2247     CryptDestroyKey(signKey);
2248     /* import the key again... */
2249     result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2250     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2251     HeapFree(GetProcessHeap(), 0, exportedKey);
2252     /* and decrypt the data encrypted with the original key with the imported
2253      * key.
2254      */
2255     result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2256     ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */),
2257        "CryptDecrypt failed: %08x\n", GetLastError());
2258     if (result)
2259     {
2260         ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2261         ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2262     }
2263     CryptDestroyKey(keyExchangeKey);
2264     CryptReleaseContext(prov, 0);
2265
2266     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2267      CRYPT_DELETEKEYSET);
2268 }
2269
2270 static void test_enum_container(void)
2271 {
2272     BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2273     DWORD dwBufferLen;
2274     BOOL result, fFound = FALSE;
2275
2276     /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2277      * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2278     SetLastError(0xdeadbeef);
2279     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2280     ok (result, "%08x\n", GetLastError());
2281     ok (dwBufferLen == MAX_PATH + 1 ||
2282         broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2283         "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2284
2285     /* If the result fits into abContainerName dwBufferLen is left untouched */
2286     dwBufferLen = (DWORD)sizeof(abContainerName);
2287     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2288     ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2289     
2290     /* We only check, if the currently open 'winetest' container is among the enumerated. */
2291     do {
2292         if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2293         dwBufferLen = (DWORD)sizeof(abContainerName);
2294     } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2295         
2296     ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2297 }
2298
2299 static BYTE signBlob[] = {
2300 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2301 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2302 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2303 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2304 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2305 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2306 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2307 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2308 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2309 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2310 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2311 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2312 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2313 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2314 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2315 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2316 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2317 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2318 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2319 0xb6,0x85,0x86,0x07 };
2320
2321 static void test_null_provider(void)
2322 {
2323     HCRYPTPROV prov;
2324     HCRYPTKEY key;
2325     BOOL result;
2326     DWORD keySpec, dataLen,dwParam;
2327     char szName[MAX_PATH];
2328
2329     result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2330     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2331      "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2332     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2333     ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2334      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2335     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2336      CRYPT_DELETEKEYSET);
2337     ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2338      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2339     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2340      CRYPT_DELETEKEYSET);
2341     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2342      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2343     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2344     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2345      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2346
2347     /* Delete the default container. */
2348     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2349     /* Once you've deleted the default container you can't open it as if it
2350      * already exists.
2351      */
2352     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2353     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2354      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2355     /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2356     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2357      CRYPT_VERIFYCONTEXT);
2358     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2359     if (!result) return;
2360     dataLen = sizeof(keySpec);
2361     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2362     if (result)
2363         ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2364          "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2365     /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2366      * supported, you can't get the keys from this container.
2367      */
2368     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2369     ok(!result && GetLastError() == NTE_NO_KEY,
2370      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2371     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2372     ok(!result && GetLastError() == NTE_NO_KEY,
2373      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2374     result = CryptReleaseContext(prov, 0);
2375     ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2376     /* You can create a new default container. */
2377     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2378      CRYPT_NEWKEYSET);
2379     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2380     /* But you still can't get the keys (until one's been generated.) */
2381     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2382     ok(!result && GetLastError() == NTE_NO_KEY,
2383      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2384     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2385     ok(!result && GetLastError() == NTE_NO_KEY,
2386      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2387     CryptReleaseContext(prov, 0);
2388     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2389
2390     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2391      CRYPT_DELETEKEYSET);
2392     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2393     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2394      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2395     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2396      CRYPT_VERIFYCONTEXT);
2397     ok(!result && GetLastError() == NTE_BAD_FLAGS,
2398      "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2399     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2400      CRYPT_NEWKEYSET);
2401     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2402     if (!result) return;
2403     /* Test provider parameters getter */
2404     dataLen = sizeof(dwParam);
2405     result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2406     ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2407         "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2408     dataLen = sizeof(dwParam);
2409     result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2410     ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2411         "Expected 0, got 0x%08X\n",dwParam);
2412     dataLen = sizeof(dwParam);
2413     result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2414     ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2415         "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2416     dataLen = sizeof(keySpec);
2417     SetLastError(0xdeadbeef);
2418     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2419     if (!result && GetLastError() == NTE_BAD_TYPE)
2420         skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2421     else
2422         ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2423             "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2424     /* PP_CONTAINER parameter */
2425     dataLen = sizeof(szName);
2426     result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2427     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2428         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2429         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2430     /* PP_UNIQUE_CONTAINER parameter */
2431     dataLen = sizeof(szName);
2432     SetLastError(0xdeadbeef);
2433     result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2434     if (!result && GetLastError() == NTE_BAD_TYPE)
2435     {
2436         skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2437     }
2438     else
2439     {
2440         char container[MAX_PATH];
2441
2442         ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2443         uniquecontainer(container);
2444         todo_wine
2445         {
2446             ok(dataLen == strlen(container)+1 ||
2447                broken(dataLen == strlen(szContainer)+1) /* WinME */,
2448                "Expected a param length of 70, got %d\n", dataLen);
2449             ok(!strcmp(container, szName) ||
2450                broken(!strcmp(szName, szContainer)) /* WinME */,
2451                "Wrong container name : %s\n", szName);
2452         }
2453     }
2454     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2455     ok(!result && GetLastError() == NTE_NO_KEY,
2456      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2457     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2458     ok(!result && GetLastError() == NTE_NO_KEY,
2459      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2460
2461     /* Importing a key exchange blob.. */
2462     result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2463      0, 0, &key);
2464     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2465     CryptDestroyKey(key);
2466     /* allows access to the key exchange key.. */
2467     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2468     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2469     CryptDestroyKey(key);
2470     /* but not to the private key. */
2471     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2472     ok(!result && GetLastError() == NTE_NO_KEY,
2473      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2474     CryptReleaseContext(prov, 0);
2475     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2476      CRYPT_DELETEKEYSET);
2477
2478     /* Whereas importing a sign blob.. */
2479     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2480      CRYPT_NEWKEYSET);
2481     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2482     if (!result) return;
2483     result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2484     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2485     CryptDestroyKey(key);
2486     /* doesn't allow access to the key exchange key.. */
2487     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2488     ok(!result && GetLastError() == NTE_NO_KEY,
2489      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2490     /* but does to the private key. */
2491     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2492     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2493     CryptDestroyKey(key);
2494     CryptReleaseContext(prov, 0);
2495
2496     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2497      CRYPT_DELETEKEYSET);
2498
2499     /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2500     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2501      CRYPT_NEWKEYSET);
2502     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2503     result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2504     ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2505     CryptDestroyKey(key);
2506     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2507     ok(!result, "expected CryptGetUserKey to fail\n");
2508     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2509     ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2510     CryptDestroyKey(key);
2511     CryptReleaseContext(prov, 0);
2512
2513     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2514      CRYPT_DELETEKEYSET);
2515
2516     /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2517     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2518      CRYPT_NEWKEYSET);
2519     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2520     result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2521     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2522     CryptDestroyKey(key);
2523     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2524     ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2525     CryptDestroyKey(key);
2526     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2527     ok(!result, "expected CryptGetUserKey to fail\n");
2528     CryptReleaseContext(prov, 0);
2529
2530     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2531      CRYPT_DELETEKEYSET);
2532
2533     /* test for the bug in accessing the user key in a container
2534      */
2535     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2536      CRYPT_NEWKEYSET);
2537     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2538     result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2539     ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2540     CryptDestroyKey(key);
2541     CryptReleaseContext(prov,0);
2542     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2543     ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2544     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2545     ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2546     CryptDestroyKey(key);
2547     CryptReleaseContext(prov, 0);
2548
2549     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2550      CRYPT_DELETEKEYSET);
2551
2552     /* test the machine key set */
2553     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2554      CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2555     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2556      CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2557     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2558     CryptReleaseContext(prov, 0);
2559     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2560      CRYPT_MACHINE_KEYSET);
2561     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2562     CryptReleaseContext(prov,0);
2563     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2564        CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2565     ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2566                 GetLastError());
2567     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2568      CRYPT_MACHINE_KEYSET);
2569     ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2570         "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2571
2572 }
2573
2574 static void test_key_permissions(void)
2575 {
2576     HCRYPTKEY hKey1, hKey2;
2577     DWORD dwVal, dwLen;
2578     BOOL result;
2579
2580     /* Create keys that are exportable */
2581     if (!init_base_environment(CRYPT_EXPORTABLE))
2582         return;
2583
2584     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2585     ok (result, "%08x\n", GetLastError());
2586     if (!result) return;
2587
2588     dwVal = 0xdeadbeef;
2589     dwLen = sizeof(DWORD);
2590     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2591     ok(result, "%08x\n", GetLastError());
2592     ok(dwVal ==
2593         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2594         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2595         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2596         " got %08x\n", dwVal);
2597
2598     /* The key exchange key's public key may be exported.. */
2599     result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2600     ok(result, "%08x\n", GetLastError());
2601     /* and its private key may be too. */
2602     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2603     ok(result, "%08x\n", GetLastError());
2604     /* Turning off the key's export permissions is "allowed".. */
2605     dwVal &= ~CRYPT_EXPORT;
2606     result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2607     ok(result ||
2608         broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2609         broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2610         "%08x\n", GetLastError());
2611     /* but it has no effect. */
2612     dwVal = 0xdeadbeef;
2613     dwLen = sizeof(DWORD);
2614     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2615     ok(result, "%08x\n", GetLastError());
2616     ok(dwVal ==
2617         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2618         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2619         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2620         " got %08x\n", dwVal);
2621     /* Thus, changing the export flag of the key doesn't affect whether the key
2622      * may be exported.
2623      */
2624     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2625     ok(result, "%08x\n", GetLastError());
2626
2627     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2628     ok (result, "%08x\n", GetLastError());
2629
2630     /* A subsequent get of the same key, into a different handle, also doesn't
2631      * show that the permissions have been changed.
2632      */
2633     dwVal = 0xdeadbeef;
2634     dwLen = sizeof(DWORD);
2635     result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2636     ok(result, "%08x\n", GetLastError());
2637     ok(dwVal ==
2638         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2639         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2640         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2641         " got %08x\n", dwVal);
2642
2643     CryptDestroyKey(hKey2);
2644     CryptDestroyKey(hKey1);
2645
2646     clean_up_base_environment();
2647 }
2648
2649 static void test_key_initialization(void)
2650 {
2651     DWORD dwLen;
2652     HCRYPTPROV prov1, prov2;
2653     HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2654     BOOL result;
2655     static BYTE abSessionKey[148] = {
2656         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2657         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2658         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2659         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2660         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2661         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2662         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2663         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2664         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2665         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2666         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2667         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2668         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2669         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2670         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2671         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2672         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2673         0x04, 0x8c, 0x49, 0x92
2674     };
2675
2676     /* Like init_base_environment, but doesn't generate new keys, as they'll
2677      * be imported instead.
2678      */
2679     if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2680     {
2681         result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2682                                      CRYPT_NEWKEYSET);
2683         ok(result, "%08x\n", GetLastError());
2684     }
2685     dwLen = (DWORD)sizeof(abPlainPrivateKey);
2686     result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2687
2688     dwLen = (DWORD)sizeof(abSessionKey);
2689     result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2690     ok(result, "%08x\n", GetLastError());
2691
2692     /* Once the key has been imported, subsequently acquiring a context with
2693      * the same name will allow retrieving the key.
2694      */
2695     result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2696     ok(result, "%08x\n", GetLastError());
2697     result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2698     ok(result, "%08x\n", GetLastError());
2699     if (result) CryptDestroyKey(hKey);
2700     CryptReleaseContext(prov2, 0);
2701
2702     CryptDestroyKey(hSessionKey);
2703     CryptDestroyKey(hKeyExchangeKey);
2704     CryptReleaseContext(prov1, 0);
2705     CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2706      CRYPT_DELETEKEYSET);
2707 }
2708
2709 START_TEST(rsaenh)
2710 {
2711     if (!init_base_environment(0))
2712         return;
2713     test_prov();
2714     test_gen_random();
2715     test_hashes();
2716     test_rc4();
2717     test_rc2();
2718     test_des();
2719     test_3des112();
2720     test_3des();
2721     test_hmac();
2722     test_mac();
2723     test_block_cipher_modes();
2724     test_import_private();
2725     test_verify_signature();
2726     test_rsa_encrypt();
2727     test_import_export();
2728     test_enum_container();
2729     clean_up_base_environment();
2730     test_key_permissions();
2731     test_key_initialization();
2732     test_schannel_provider();
2733     test_null_provider();
2734     test_rsa_round_trip();
2735     if (!init_aes_environment())
2736         return;
2737     test_aes(128);
2738     test_aes(192);
2739     test_aes(256);
2740     test_sha2();
2741     clean_up_aes_environment();
2742 }