oleaut32: Do no check for dispatchable flag on dual interfaces.
[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_ASE 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(abData));
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, "CryptEncrypt failed: %08x\n", GetLastError());
2064     /* export the key... */
2065     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2066                             &keyLen);
2067     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2068     exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2069     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2070                             &keyLen);
2071     /* destroy the key... */
2072     CryptDestroyKey(keyExchangeKey);
2073     CryptDestroyKey(signKey);
2074     /* import the key again... */
2075     result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2076     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2077     HeapFree(GetProcessHeap(), 0, exportedKey);
2078     /* and decrypt the data encrypted with the original key with the imported
2079      * key.
2080      */
2081     result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2082     ok(result, "CryptDecrypt failed: %08x\n", GetLastError());
2083     if (result)
2084     {
2085         ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2086         ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value");
2087     }
2088     CryptReleaseContext(prov, 0);
2089
2090     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2091      CRYPT_DELETEKEYSET);
2092 }
2093
2094 static void test_enum_container(void)
2095 {
2096     BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2097     DWORD dwBufferLen;
2098     BOOL result, fFound = FALSE;
2099
2100     /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2101      * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2102     SetLastError(0xdeadbeef);
2103     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2104     ok (result, "%08x\n", GetLastError());
2105     ok (dwBufferLen == MAX_PATH + 1 ||
2106         broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2107         "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2108
2109     /* If the result fits into abContainerName dwBufferLen is left untouched */
2110     dwBufferLen = (DWORD)sizeof(abContainerName);
2111     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2112     ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2113     
2114     /* We only check, if the currently open 'winetest' container is among the enumerated. */
2115     do {
2116         if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2117         dwBufferLen = (DWORD)sizeof(abContainerName);
2118     } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2119         
2120     ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2121 }
2122
2123 static BYTE signBlob[] = {
2124 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2125 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2126 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2127 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2128 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2129 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2130 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2131 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2132 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2133 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2134 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2135 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2136 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2137 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2138 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2139 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2140 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2141 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2142 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2143 0xb6,0x85,0x86,0x07 };
2144
2145 static void test_null_provider(void)
2146 {
2147     HCRYPTPROV prov;
2148     HCRYPTKEY key;
2149     BOOL result;
2150     DWORD keySpec, dataLen,dwParam;
2151     char szName[MAX_PATH];
2152
2153     result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2154     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2155      "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2156     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2157     ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2158      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2159     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2160      CRYPT_DELETEKEYSET);
2161     ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2162      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2163     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2164      CRYPT_DELETEKEYSET);
2165     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2166      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2167     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2168     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2169      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2170
2171     /* Delete the default container. */
2172     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2173     /* Once you've deleted the default container you can't open it as if it
2174      * already exists.
2175      */
2176     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2177     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2178      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2179     /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2180     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2181      CRYPT_VERIFYCONTEXT);
2182     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2183     if (!result) return;
2184     dataLen = sizeof(keySpec);
2185     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2186     if (result)
2187         ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2188          "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2189     /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2190      * supported, you can't get the keys from this container.
2191      */
2192     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2193     ok(!result && GetLastError() == NTE_NO_KEY,
2194      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2195     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2196     ok(!result && GetLastError() == NTE_NO_KEY,
2197      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2198     result = CryptReleaseContext(prov, 0);
2199     ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2200     /* You can create a new default container. */
2201     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2202      CRYPT_NEWKEYSET);
2203     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2204     /* But you still can't get the keys (until one's been generated.) */
2205     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2206     ok(!result && GetLastError() == NTE_NO_KEY,
2207      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2208     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2209     ok(!result && GetLastError() == NTE_NO_KEY,
2210      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2211     CryptReleaseContext(prov, 0);
2212     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2213
2214     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2215      CRYPT_DELETEKEYSET);
2216     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2217     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2218      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2219     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2220      CRYPT_VERIFYCONTEXT);
2221     ok(!result && GetLastError() == NTE_BAD_FLAGS,
2222      "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2223     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2224      CRYPT_NEWKEYSET);
2225     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2226     if (!result) return;
2227     /* Test provider parameters getter */
2228     dataLen = sizeof(dwParam);
2229     result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2230     ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2231         "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2232     dataLen = sizeof(dwParam);
2233     result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2234     ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2235         "Expected 0, got 0x%08X\n",dwParam);
2236     dataLen = sizeof(dwParam);
2237     result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2238     ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2239         "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2240     dataLen = sizeof(keySpec);
2241     SetLastError(0xdeadbeef);
2242     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2243     if (!result && GetLastError() == NTE_BAD_TYPE)
2244         skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2245     else
2246         ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2247             "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2248     /* PP_CONTAINER parameter */
2249     dataLen = sizeof(szName);
2250     result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2251     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2252         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2253         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2254     /* PP_UNIQUE_CONTAINER parameter */
2255     dataLen = sizeof(szName);
2256     SetLastError(0xdeadbeef);
2257     result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2258     if (!result && GetLastError() == NTE_BAD_TYPE)
2259     {
2260         skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2261     }
2262     else
2263     {
2264         char container[MAX_PATH];
2265
2266         ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2267         uniquecontainer(container);
2268         todo_wine
2269         {
2270             ok(dataLen == strlen(container)+1 ||
2271                broken(dataLen == strlen(szContainer)+1) /* WinME */,
2272                "Expected a param length of 70, got %d\n", dataLen);
2273             ok(!strcmp(container, szName) ||
2274                broken(!strcmp(szName, szContainer)) /* WinME */,
2275                "Wrong container name : %s\n", szName);
2276         }
2277     }
2278     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2279     ok(!result && GetLastError() == NTE_NO_KEY,
2280      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2281     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2282     ok(!result && GetLastError() == NTE_NO_KEY,
2283      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2284
2285     /* Importing a key exchange blob.. */
2286     result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2287      0, 0, &key);
2288     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2289     CryptDestroyKey(key);
2290     /* allows access to the key exchange key.. */
2291     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2292     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2293     CryptDestroyKey(key);
2294     /* but not to the private key. */
2295     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2296     ok(!result && GetLastError() == NTE_NO_KEY,
2297      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2298     CryptReleaseContext(prov, 0);
2299     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2300      CRYPT_DELETEKEYSET);
2301
2302     /* Whereas importing a sign blob.. */
2303     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2304      CRYPT_NEWKEYSET);
2305     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2306     if (!result) return;
2307     result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2308     ok(result, "CryptGenKey failed: %08x\n", GetLastError());
2309     CryptDestroyKey(key);
2310     /* doesn't allow access to the key exchange key.. */
2311     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2312     ok(!result && GetLastError() == NTE_NO_KEY,
2313      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2314     /* but does to the private key. */
2315     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2316     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2317     CryptDestroyKey(key);
2318     CryptReleaseContext(prov, 0);
2319
2320     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2321      CRYPT_DELETEKEYSET);
2322
2323     /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2324     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2325      CRYPT_NEWKEYSET);
2326     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2327     result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2328     ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2329     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2330     ok(!result, "expected CryptGetUserKey to fail\n");
2331     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2332     ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2333     CryptDestroyKey(key);
2334     CryptReleaseContext(prov, 0);
2335
2336     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2337      CRYPT_DELETEKEYSET);
2338
2339     /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2340     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2341      CRYPT_NEWKEYSET);
2342     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2343     result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2344     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2345     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2346     ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2347     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2348     ok(!result, "expected CryptGetUserKey to fail\n");
2349     CryptDestroyKey(key);
2350     CryptReleaseContext(prov, 0);
2351
2352     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2353      CRYPT_DELETEKEYSET);
2354
2355     /* test for the bug in accessing the user key in a container
2356      */
2357     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2358      CRYPT_NEWKEYSET);
2359     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2360     result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2361     ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2362     CryptDestroyKey(key);
2363     CryptReleaseContext(prov,0);
2364     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2365     ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2366     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2367     ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2368     CryptDestroyKey(key);
2369     CryptReleaseContext(prov, 0);
2370
2371     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2372      CRYPT_DELETEKEYSET);
2373
2374     /* test the machine key set */
2375     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2376      CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2377     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2378      CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2379     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2380     CryptReleaseContext(prov, 0);
2381     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2382      CRYPT_MACHINE_KEYSET);
2383     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2384     CryptReleaseContext(prov,0);
2385     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2386        CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2387     ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2388                 GetLastError());
2389     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2390      CRYPT_MACHINE_KEYSET);
2391     ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2392         "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2393
2394 }
2395
2396 static void test_key_permissions(void)
2397 {
2398     HCRYPTKEY hKey1, hKey2;
2399     DWORD dwVal, dwLen;
2400     BOOL result;
2401
2402     /* Create keys that are exportable */
2403     if (!init_base_environment(CRYPT_EXPORTABLE))
2404         return;
2405
2406     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2407     ok (result, "%08x\n", GetLastError());
2408     if (!result) return;
2409
2410     dwVal = 0xdeadbeef;
2411     dwLen = sizeof(DWORD);
2412     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2413     ok(result, "%08x\n", GetLastError());
2414     ok(dwVal ==
2415         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2416         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2417         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2418         " got %08x\n", dwVal);
2419
2420     /* The key exchange key's public key may be exported.. */
2421     result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2422     ok(result, "%08x\n", GetLastError());
2423     /* and its private key may be too. */
2424     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2425     ok(result, "%08x\n", GetLastError());
2426     /* Turning off the key's export permissions is "allowed".. */
2427     dwVal &= ~CRYPT_EXPORT;
2428     result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2429     ok(result ||
2430         broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2431         broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2432         "%08x\n", GetLastError());
2433     /* but it has no effect. */
2434     dwVal = 0xdeadbeef;
2435     dwLen = sizeof(DWORD);
2436     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2437     ok(result, "%08x\n", GetLastError());
2438     ok(dwVal ==
2439         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2440         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2441         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2442         " got %08x\n", dwVal);
2443     /* Thus, changing the export flag of the key doesn't affect whether the key
2444      * may be exported.
2445      */
2446     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2447     ok(result, "%08x\n", GetLastError());
2448
2449     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2450     ok (result, "%08x\n", GetLastError());
2451
2452     /* A subsequent get of the same key, into a different handle, also doesn't
2453      * show that the permissions have been changed.
2454      */
2455     dwVal = 0xdeadbeef;
2456     dwLen = sizeof(DWORD);
2457     result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2458     ok(result, "%08x\n", GetLastError());
2459     ok(dwVal ==
2460         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2461         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2462         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2463         " got %08x\n", dwVal);
2464
2465     CryptDestroyKey(hKey2);
2466     CryptDestroyKey(hKey1);
2467
2468     clean_up_base_environment();
2469 }
2470
2471 static void test_key_initialization(void)
2472 {
2473     DWORD dwLen;
2474     HCRYPTPROV prov1, prov2;
2475     HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2476     BOOL result;
2477     static BYTE abSessionKey[148] = {
2478         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2479         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2480         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2481         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2482         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2483         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2484         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2485         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2486         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2487         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2488         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2489         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2490         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2491         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2492         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2493         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2494         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2495         0x04, 0x8c, 0x49, 0x92
2496     };
2497
2498     /* Like init_base_environment, but doesn't generate new keys, as they'll
2499      * be imported instead.
2500      */
2501     if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2502     {
2503         result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2504                                      CRYPT_NEWKEYSET);
2505         ok(result, "%08x\n", GetLastError());
2506     }
2507     dwLen = (DWORD)sizeof(abPlainPrivateKey);
2508     result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2509
2510     dwLen = (DWORD)sizeof(abSessionKey);
2511     result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2512     ok(result, "%08x\n", GetLastError());
2513
2514     /* Once the key has been imported, subsequently acquiring a context with
2515      * the same name will allow retrieving the key.
2516      */
2517     result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2518     ok(result, "%08x\n", GetLastError());
2519     result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2520     ok(result, "%08x\n", GetLastError());
2521     if (result) CryptDestroyKey(hKey);
2522     CryptReleaseContext(prov2, 0);
2523
2524     CryptDestroyKey(hSessionKey);
2525     CryptDestroyKey(hKeyExchangeKey);
2526     CryptReleaseContext(prov1, 0);
2527     CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2528      CRYPT_DELETEKEYSET);
2529 }
2530
2531 START_TEST(rsaenh)
2532 {
2533     if (!init_base_environment(0))
2534         return;
2535     test_prov();
2536     test_gen_random();
2537     test_hashes();
2538     test_rc4();
2539     test_rc2();
2540     test_des();
2541     test_3des112();
2542     test_3des();
2543     test_hmac();
2544     test_mac();
2545     test_block_cipher_modes();
2546     test_import_private();
2547     test_verify_signature();
2548     test_rsa_encrypt();
2549     test_import_export();
2550     test_enum_container();
2551     clean_up_base_environment();
2552     test_key_permissions();
2553     test_key_initialization();
2554     test_schannel_provider();
2555     test_null_provider();
2556     test_rsa_round_trip();
2557     if (!init_aes_environment())
2558         return;
2559     test_aes(128);
2560     test_aes(192);
2561     test_aes(256);
2562     clean_up_aes_environment();
2563 }