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