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