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