rsaenh/tests: Fix a test failure on Win98.
[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(void)
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, 0, &hKey);
136         ok(result, "%08x\n", GetLastError());
137         if (result) CryptDestroyKey(hKey);
138         result = CryptGenKey(hProv, AT_SIGNATURE, 0, &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, (BYTE*)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, (BYTE*)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, (BYTE*)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, (BYTE*)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, (BYTE*)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, (BYTE*)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, (BYTE*)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         dwLen = sizeof(DWORD);
792         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
793         ok(result, "%08x\n", GetLastError());
794
795         dwLen = sizeof(DWORD);
796         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
797         ok(result, "%08x\n", GetLastError());
798
799         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
800         ok(result, "%08x\n", GetLastError());
801         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
802         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
803         HeapFree(GetProcessHeap(), 0, pbTemp);
804
805         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
806         ok(result, "%08x\n", GetLastError());
807         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
808         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
809         HeapFree(GetProcessHeap(), 0, pbTemp);
810
811         dwLen = sizeof(DWORD);
812         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
813
814         result = CryptDestroyHash(hHash);
815         ok(result, "%08x\n", GetLastError());
816
817         dwDataLen = 13;
818         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
819         ok(result, "%08x\n", GetLastError());
820
821         ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
822
823         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
824         ok(result, "%08x\n", GetLastError());
825         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
826         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
827         HeapFree(GetProcessHeap(), 0, pbTemp);
828
829         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
830         ok(result, "%08x\n", GetLastError());
831
832         /* What sizes salt can I set? */
833         salt.pbData = pbData;
834         for (i=0; i<24; i++)
835         {
836             salt.cbData = i;
837             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
838             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
839         }
840         salt.cbData = 25;
841         SetLastError(0xdeadbeef);
842         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
843         ok(!result ||
844            broken(result), /* Win9x, WinMe, NT4, W2K */
845            "%08x\n", GetLastError());
846
847         result = CryptDestroyKey(hKey);
848         ok(result, "%08x\n", GetLastError());
849     }
850
851     /* Again, but test setting the effective key len */
852     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
853
854     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
855     if (!result) {
856         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
857     } else {
858         result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
859         ok(result, "%08x\n", GetLastError());
860
861         dwLen = 16;
862         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
863         ok(result, "%08x\n", GetLastError());
864
865         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
866         ok(result, "%08x\n", GetLastError());
867
868         SetLastError(0xdeadbeef);
869         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
870         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
871         dwKeyLen = 0;
872         SetLastError(0xdeadbeef);
873         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
874         ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
875         dwKeyLen = 1025;
876         SetLastError(0xdeadbeef);
877         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
878
879         dwLen = sizeof(dwKeyLen);
880         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
881         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
882         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
883         ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
884
885         dwKeyLen = 128;
886         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
887         ok(result, "%d\n", GetLastError());
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 == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
894
895         result = CryptDestroyHash(hHash);
896         ok(result, "%08x\n", GetLastError());
897
898         dwDataLen = 13;
899         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
900         ok(result, "%08x\n", GetLastError());
901
902         ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
903                 "RC2 encryption failed!\n");
904
905         /* Oddly enough this succeeds, though it should have no effect */
906         dwKeyLen = 40;
907         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
908         ok(result, "%d\n", GetLastError());
909
910         result = CryptDestroyKey(hKey);
911         ok(result, "%08x\n", GetLastError());
912     }
913 }
914
915 static void test_rc4(void)
916 {
917     static const BYTE rc4[16] = { 
918         0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0, 
919         0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };    
920     BOOL result;
921     HCRYPTHASH hHash;
922     HCRYPTKEY hKey;
923     DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
924     unsigned char pbData[2000], *pbTemp;
925     unsigned char pszBuffer[256];
926     int i;
927
928     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
929
930     /* MD2 Hashing */
931     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
932     if (!result) {
933         /* rsaenh compiled without OpenSSL */
934         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
935     } else {
936         CRYPT_INTEGER_BLOB salt;
937
938         result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
939            ok(result, "%08x\n", GetLastError());
940
941         dwLen = 16;
942         result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
943         ok(result, "%08x\n", GetLastError());
944
945         result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
946         ok(result, "%08x\n", GetLastError());
947
948         dwLen = sizeof(DWORD);
949         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
950         ok(result, "%08x\n", GetLastError());
951
952         dwLen = sizeof(DWORD);
953         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
954         ok(result, "%08x\n", GetLastError());
955
956         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
957         ok(result, "%08x\n", GetLastError());
958         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
959         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
960         HeapFree(GetProcessHeap(), 0, pbTemp);
961
962         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
963         ok(result, "%08x\n", GetLastError());
964         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
965         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
966         HeapFree(GetProcessHeap(), 0, pbTemp);
967
968         dwLen = sizeof(DWORD);
969         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
970
971         result = CryptDestroyHash(hHash);
972         ok(result, "%08x\n", GetLastError());
973
974         dwDataLen = 16;
975         result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
976         ok(result, "%08x\n", GetLastError());
977         dwDataLen = 16;
978         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
979         ok(result, "%08x\n", GetLastError());
980
981         ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
982
983         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
984         ok(result, "%08x\n", GetLastError());
985
986         /* What sizes salt can I set? */
987         salt.pbData = pbData;
988         for (i=0; i<24; i++)
989         {
990             salt.cbData = i;
991             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
992             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
993         }
994         salt.cbData = 25;
995         SetLastError(0xdeadbeef);
996         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
997         ok(!result ||
998            broken(result), /* Win9x, WinMe, NT4, W2K */
999            "%08x\n", GetLastError());
1000
1001         result = CryptDestroyKey(hKey);
1002         ok(result, "%08x\n", GetLastError());
1003     }
1004 }
1005
1006 static void test_hmac(void) {
1007     HCRYPTKEY hKey;
1008     HCRYPTHASH hHash;
1009     BOOL result;
1010     /* Using CALG_MD2 here fails on Windows 2003, why ? */
1011     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1012     DWORD dwLen;
1013     BYTE abData[256];
1014     static const BYTE hmac[16] = { 
1015         0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c, 
1016         0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1017     int i;
1018
1019     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1020
1021     if (!derive_key(CALG_RC2, &hKey, 56)) return;
1022
1023     result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1024     ok(result, "%08x\n", GetLastError());
1025     if (!result) return;
1026
1027     result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1028     ok(result, "%08x\n", GetLastError());
1029
1030     result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
1031     ok(result, "%08x\n", GetLastError());
1032
1033     dwLen = sizeof(abData)/sizeof(BYTE);
1034     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1035     ok(result, "%08x\n", GetLastError());
1036
1037     ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1038     
1039     result = CryptDestroyHash(hHash);
1040     ok(result, "%08x\n", GetLastError());
1041     
1042     result = CryptDestroyKey(hKey);
1043     ok(result, "%08x\n", GetLastError());
1044
1045     /* Provoke errors */
1046     result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1047     ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1048 }
1049
1050 static void test_mac(void) {
1051     HCRYPTKEY hKey;
1052     HCRYPTHASH hHash;
1053     BOOL result;
1054     DWORD dwLen;
1055     BYTE abData[256], abEnc[264];
1056     static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1057     int i;
1058
1059     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1060     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1061
1062     if (!derive_key(CALG_RC2, &hKey, 40)) return;
1063
1064     dwLen = 256;
1065     result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1066     ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1067     
1068     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1069     ok(result, "%08x\n", GetLastError());
1070     if (!result) return;
1071
1072     result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
1073     ok(result, "%08x\n", GetLastError());
1074
1075     dwLen = sizeof(abData)/sizeof(BYTE);
1076     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1077     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1078
1079     ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1080     
1081     result = CryptDestroyHash(hHash);
1082     ok(result, "%08x\n", GetLastError());
1083     
1084     result = CryptDestroyKey(hKey);
1085     ok(result, "%08x\n", GetLastError());
1086     
1087     /* Provoke errors */
1088     if (!derive_key(CALG_RC4, &hKey, 56)) return;
1089
1090     SetLastError(0xdeadbeef);
1091     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1092     ok((!result && GetLastError() == NTE_BAD_KEY) ||
1093             broken(result), /* Win9x, WinMe, NT4, W2K */
1094             "%08x\n", GetLastError());
1095
1096     result = CryptDestroyKey(hKey);
1097     ok(result, "%08x\n", GetLastError());
1098 }
1099
1100 static BYTE abPlainPrivateKey[596] = {
1101     0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1102     0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1103     0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1104     0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1105     0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1106     0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1107     0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1108     0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1109     0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1110     0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1111     0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1112     0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1113     0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1114     0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1115     0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1116     0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1117     0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1118     0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1119     0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1120     0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1121     0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1122     0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1123     0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1124     0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1125     0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1126     0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1127     0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1128     0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1129     0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1130     0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1131     0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1132     0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1133     0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1134     0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1135     0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1136     0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1137     0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1138     0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1139     0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1140     0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1141     0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1142     0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1143     0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1144     0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1145     0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1146     0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1147     0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1148     0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1149     0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1150     0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1151     0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1152     0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1153     0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1154     0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1155     0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1156     0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1157     0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1158     0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1159     0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1160     0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1161     0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1162     0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1163     0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1164     0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1165     0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1166     0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1167     0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1168     0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1169     0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1170     0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1171     0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1172     0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1173     0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1174     0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1175     0xf2, 0x5d, 0x58, 0x07
1176 };
1177
1178 static void test_import_private(void) 
1179 {
1180     DWORD dwLen;
1181     HCRYPTKEY hKeyExchangeKey, hSessionKey;
1182     BOOL result;
1183     static BYTE abSessionKey[148] = {
1184         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1185         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1186         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1187         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1188         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1189         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1190         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1191         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1192         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1193         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1194         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1195         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1196         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1197         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1198         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1199         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1200         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1201         0x04, 0x8c, 0x49, 0x92
1202     };
1203     static BYTE abEncryptedMessage[12] = {
1204         0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1205         0x1c, 0xfd, 0xde, 0x71
1206     };
1207             
1208     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1209     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1210     if (!result) {
1211         /* rsaenh compiled without OpenSSL */
1212         ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1213         return;
1214     }
1215
1216     dwLen = (DWORD)sizeof(abSessionKey);
1217     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1218     ok(result, "%08x\n", GetLastError());
1219     if (!result) return;
1220
1221     dwLen = (DWORD)sizeof(abEncryptedMessage);
1222     result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1223     ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12), 
1224        "%08x, len: %d\n", GetLastError(), dwLen);
1225     CryptDestroyKey(hSessionKey);
1226     
1227     if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1228
1229     dwLen = (DWORD)sizeof(abSessionKey);
1230     result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1231     ok(result, "%08x\n", GetLastError());
1232     CryptDestroyKey(hSessionKey);
1233     if (!result) return;
1234
1235     dwLen = (DWORD)sizeof(abSessionKey);
1236     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1237     ok(result, "%08x\n", GetLastError());
1238     if (!result) return;
1239
1240     CryptDestroyKey(hSessionKey);
1241     CryptDestroyKey(hKeyExchangeKey);
1242 }
1243
1244 static void test_verify_signature(void) {
1245     HCRYPTHASH hHash;
1246     HCRYPTKEY hPubSignKey;
1247     BYTE abData[] = "Wine rocks!";
1248     BOOL result;
1249     BYTE abPubKey[148] = {
1250         0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 
1251         0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 
1252         0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19, 
1253         0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27, 
1254         0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8, 
1255         0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda, 
1256         0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a, 
1257         0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc, 
1258         0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c, 
1259         0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c, 
1260         0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89, 
1261         0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b, 
1262         0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa, 
1263         0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63, 
1264         0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff, 
1265         0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49, 
1266         0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87, 
1267         0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7, 
1268         0xe1, 0x21, 0x50, 0xac
1269     };
1270     /* md2 with hash oid */
1271     BYTE abSignatureMD2[128] = {
1272         0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67, 
1273         0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b, 
1274         0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda, 
1275         0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59, 
1276         0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a, 
1277         0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34, 
1278         0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40, 
1279         0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7, 
1280         0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0, 
1281         0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06, 
1282         0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51, 
1283         0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f, 
1284         0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46, 
1285         0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25, 
1286         0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0, 
1287         0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1288     };
1289     /* md2 without hash oid */
1290     BYTE abSignatureMD2NoOID[128] = {
1291         0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d, 
1292         0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19, 
1293         0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd, 
1294         0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4, 
1295         0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65, 
1296         0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99, 
1297         0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf, 
1298         0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc, 
1299         0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0, 
1300         0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01, 
1301         0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7, 
1302         0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f, 
1303         0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a, 
1304         0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9, 
1305         0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06, 
1306         0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1307     };
1308     /* md4 with hash oid */
1309     BYTE abSignatureMD4[128] = {
1310         0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51, 
1311         0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b, 
1312         0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2, 
1313         0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e, 
1314         0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13, 
1315         0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9, 
1316         0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f, 
1317         0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96, 
1318         0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9, 
1319         0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e, 
1320         0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0, 
1321         0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe, 
1322         0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18, 
1323         0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab, 
1324         0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3, 
1325         0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1326     };
1327     /* md4 without hash oid */
1328     BYTE abSignatureMD4NoOID[128] = {
1329         0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda, 
1330         0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24, 
1331         0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0, 
1332         0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36, 
1333         0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85, 
1334         0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3, 
1335         0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f, 
1336         0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9, 
1337         0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06, 
1338         0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f, 
1339         0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb, 
1340         0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96, 
1341         0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f, 
1342         0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9, 
1343         0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb, 
1344         0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1345     }; 
1346     /* md5 with hash oid */
1347     BYTE abSignatureMD5[128] = {
1348         0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5, 
1349         0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f, 
1350         0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7, 
1351         0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98, 
1352         0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec, 
1353         0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5, 
1354         0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04, 
1355         0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b, 
1356         0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95, 
1357         0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c, 
1358         0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29, 
1359         0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9, 
1360         0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c, 
1361         0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90, 
1362         0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e, 
1363         0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1364     };
1365     /* md5 without hash oid */
1366     BYTE abSignatureMD5NoOID[128] = {
1367         0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f, 
1368         0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75, 
1369         0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f, 
1370         0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d, 
1371         0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f, 
1372         0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49, 
1373         0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8, 
1374         0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c, 
1375         0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23, 
1376         0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19, 
1377         0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb, 
1378         0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3, 
1379         0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b, 
1380         0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b, 
1381         0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5, 
1382         0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1383     };
1384     /* sha with hash oid */
1385     BYTE abSignatureSHA[128] = {
1386         0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91, 
1387         0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd, 
1388         0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24, 
1389         0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94, 
1390         0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f, 
1391         0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a, 
1392         0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52, 
1393         0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20, 
1394         0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5, 
1395         0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a, 
1396         0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff, 
1397         0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53, 
1398         0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00, 
1399         0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e, 
1400         0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98, 
1401         0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1402     };
1403     /* sha without hash oid */
1404     BYTE abSignatureSHANoOID[128] = {
1405         0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6, 
1406         0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a, 
1407         0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f, 
1408         0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37, 
1409         0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65, 
1410         0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe, 
1411         0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6, 
1412         0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe, 
1413         0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c, 
1414         0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4, 
1415         0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80, 
1416         0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a, 
1417         0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00, 
1418         0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd, 
1419         0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67, 
1420         0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1421     }; 
1422     
1423     result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1424     ok(result, "%08x\n", GetLastError());
1425     if (!result) return;
1426
1427     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1428     ok(result, "%08x\n", GetLastError());
1429     if (!result) return;
1430
1431     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1432     ok(result, "%08x\n", GetLastError());
1433     if (!result) return;
1434
1435     /*check that a NULL pointer signature is correctly handled*/
1436     result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1437     ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1438      "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1439     if (result) return;
1440
1441     /* check that we get a bad signature error when the signature is too short*/
1442     SetLastError(0xdeadbeef);
1443     result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1444     ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1445      broken(result), /* Win9x, WinMe, NT4 */
1446      "Expected NTE_BAD_SIGNATURE, got %08x\n",  GetLastError());
1447
1448     result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1449     ok(result, "%08x\n", GetLastError());
1450     if (!result) return;
1451
1452     result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1453     ok(result, "%08x\n", GetLastError());
1454     if (!result) return;
1455
1456     /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about 
1457      * the OID at all. */
1458     /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1459     ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1460     if (result) return;*/
1461
1462     CryptDestroyHash(hHash);
1463
1464     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1465     ok(result, "%08x\n", GetLastError());
1466     if (!result) return;
1467
1468     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1469     ok(result, "%08x\n", GetLastError());
1470     if (!result) return;
1471
1472     result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1473     ok(result, "%08x\n", GetLastError());
1474     if (!result) return;
1475
1476     result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1477     ok(result, "%08x\n", GetLastError());
1478     if (!result) return;
1479
1480     CryptDestroyHash(hHash);
1481
1482     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1483     ok(result, "%08x\n", GetLastError());
1484     if (!result) return;
1485
1486     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1487     ok(result, "%08x\n", GetLastError());
1488     if (!result) return;
1489
1490     result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1491     ok(result, "%08x\n", GetLastError());
1492     if (!result) return;
1493
1494     result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1495     ok(result, "%08x\n", GetLastError());
1496     if (!result) return;
1497
1498     CryptDestroyHash(hHash);
1499
1500     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1501     ok(result, "%08x\n", GetLastError());
1502     if (!result) return;
1503
1504     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1505     ok(result, "%08x\n", GetLastError());
1506     if (!result) return;
1507
1508     result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1509     ok(result, "%08x\n", GetLastError());
1510     if (!result) return;
1511
1512     result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1513     ok(result, "%08x\n", GetLastError());
1514     if (!result) return;
1515
1516     CryptDestroyHash(hHash);
1517     CryptDestroyKey(hPubSignKey);
1518 }
1519
1520 static void test_rsa_encrypt(void)
1521 {
1522     HCRYPTKEY hRSAKey;
1523     BYTE abData[2048] = "Wine rocks!";
1524     BOOL result;
1525     DWORD dwLen;
1526
1527     /* It is allowed to use the key exchange key for encryption/decryption */
1528     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1529     ok (result, "%08x\n", GetLastError());
1530     if (!result) return;
1531
1532     dwLen = 12;
1533     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1534     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1535     ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1536     dwLen = 12;
1537     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1538     ok (result, "%08x\n", GetLastError());
1539     if (!result) return;
1540
1541     result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1542     ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1543     
1544     CryptDestroyKey(hRSAKey);
1545
1546     /* It is not allowed to use the signature key for encryption/decryption */
1547     result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1548     ok (result, "%08x\n", GetLastError());
1549     if (!result) return;
1550
1551     dwLen = 12;
1552     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1553     ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1554
1555     CryptDestroyKey(hRSAKey);
1556 }
1557
1558 static void test_import_export(void)
1559 {
1560     DWORD dwLen, dwDataLen;
1561     HCRYPTKEY hPublicKey;
1562     BOOL result;
1563     ALG_ID algID;
1564     BYTE emptyKey[2048];
1565     static BYTE abPlainPublicKey[84] = {
1566         0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1567         0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1568         0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1569         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1570         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1571         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1572         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1573         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1574         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1575         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1576         0x11, 0x11, 0x11, 0x11
1577     };
1578
1579     dwLen=84;
1580     result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1581     ok(result, "failed to import the public key\n");
1582
1583     dwDataLen=sizeof(algID);
1584     result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1585     ok(result, "failed to get the KP_ALGID from the imported public key\n");
1586     ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1587         
1588     result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1589     ok(result, "failed to export the fresh imported public key\n");
1590     ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1591     ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1592
1593     CryptDestroyKey(hPublicKey);
1594 }
1595         
1596 static void test_schannel_provider(void)
1597 {
1598     HCRYPTPROV hProv;
1599     HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1600     HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1601     BOOL result;
1602     DWORD dwLen;
1603     SCHANNEL_ALG saSChannelAlg;
1604     CRYPT_DATA_BLOB data_blob;
1605     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1606     BYTE abTLS1Master[140] = {
1607         0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00, 
1608         0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68, 
1609         0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97, 
1610         0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53, 
1611         0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24, 
1612         0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3, 
1613         0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8, 
1614         0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d, 
1615         0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e, 
1616         0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e, 
1617         0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40, 
1618         0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b, 
1619         0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb, 
1620         0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6, 
1621         0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac, 
1622         0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41, 
1623         0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4, 
1624         0xd3, 0x1e, 0x82, 0xb3
1625     };
1626     BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1627     BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1628     BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1629     BYTE abClientFinished[16] = "client finished";
1630     BYTE abData[16] = "Wine rocks!";
1631     BYTE abMD5Hash[16];
1632     static const BYTE abEncryptedData[16] = {
1633         0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1634         0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d    
1635     };
1636     static const BYTE abPRF[16] = {
1637         0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1638         0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1639     };
1640     static const BYTE abMD5[16] = {
1641         0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1642         0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1643     };
1644     
1645     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1646     if (!result)
1647     {
1648         win_skip("no PROV_RSA_SCHANNEL support\n");
1649         return;
1650     }
1651     ok (result, "%08x\n", GetLastError());
1652     if (result)
1653         CryptReleaseContext(hProv, 0);
1654
1655     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1656     ok (result, "%08x\n", GetLastError());
1657     if (!result) return;
1658     
1659     /* To get deterministic results, we import the TLS1 master secret (which
1660      * is typically generated from a random generator). Therefore, we need
1661      * an RSA key. */
1662     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1663     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1664     ok (result, "%08x\n", GetLastError());
1665     if (!result) return;
1666
1667     dwLen = (DWORD)sizeof(abTLS1Master);
1668     result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1669     ok (result, "%08x\n", GetLastError());
1670     if (!result) return;    
1671    
1672     /* Setting the TLS1 client and server random parameters, as well as the 
1673      * MAC and encryption algorithm parameters. */
1674     data_blob.cbData = 33;
1675     data_blob.pbData = abClientSecret;
1676     result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1677     ok (result, "%08x\n", GetLastError());
1678     if (!result) return;
1679
1680     data_blob.cbData = 33;
1681     data_blob.pbData = abServerSecret;
1682     result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1683     ok (result, "%08x\n", GetLastError());
1684     if (!result) return;
1685     
1686     saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1687     saSChannelAlg.Algid = CALG_DES;
1688     saSChannelAlg.cBits = 64;
1689     saSChannelAlg.dwFlags = 0;
1690     saSChannelAlg.dwReserved = 0;
1691     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1692     ok (result, "%08x\n", GetLastError());
1693     if (!result) return;
1694
1695     saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1696     saSChannelAlg.Algid = CALG_MD5;
1697     saSChannelAlg.cBits = 128;
1698     saSChannelAlg.dwFlags = 0;
1699     saSChannelAlg.dwReserved = 0;
1700     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1701     ok (result, "%08x\n", GetLastError());
1702     if (!result) return;
1703
1704     /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1705      * (Keys can only be derived from hashes, not from other keys.) */
1706     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1707     ok (result, "%08x\n", GetLastError());
1708     if (!result) return;
1709
1710     /* Deriving the server write encryption key from the master hash */
1711     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1712     ok (result, "%08x\n", GetLastError());
1713     if (!result) return;
1714
1715     /* Encrypting some data with the server write encryption key and checking the result. */
1716     dwLen = 12;
1717     result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1718     ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1719
1720     /* Second test case: Test the TLS1 pseudo random number function. */
1721     result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1722     ok (result, "%08x\n", GetLastError());
1723     if (!result) return;
1724
1725     /* Set the label and seed parameters for the random number function */
1726     data_blob.cbData = 36;
1727     data_blob.pbData = abHashedHandshakes;
1728     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1729     ok (result, "%08x\n", GetLastError());
1730     if (!result) return;
1731
1732     data_blob.cbData = 15;
1733     data_blob.pbData = abClientFinished;
1734     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1735     ok (result, "%08x\n", GetLastError());
1736     if (!result) return;
1737
1738     /* Generate some pseudo random bytes and check if they are correct. */
1739     dwLen = (DWORD)sizeof(abData);
1740     result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1741     ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)), 
1742         "%08x\n", GetLastError());
1743
1744     /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1745      * Hash some data with the HMAC. Compare results. */
1746     result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1747     ok (result, "%08x\n", GetLastError());
1748     if (!result) return;
1749     
1750     result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1751     ok (result, "%08x\n", GetLastError());
1752     if (!result) return;
1753
1754     result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1755     ok (result, "%08x\n", GetLastError());
1756     if (!result) return;
1757
1758     result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1759     ok (result, "%08x\n", GetLastError());
1760     if (!result) return;
1761
1762     dwLen = (DWORD)sizeof(abMD5Hash);
1763     result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1764     ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1765
1766     CryptDestroyHash(hHMAC);
1767     CryptDestroyHash(hTLS1PRF);
1768     CryptDestroyHash(hMasterHash);
1769     CryptDestroyKey(hServerWriteMACKey);
1770     CryptDestroyKey(hServerWriteKey);
1771     CryptDestroyKey(hRSAKey);
1772     CryptDestroyKey(hMasterSecret);
1773     CryptReleaseContext(hProv, 0);
1774     CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1775 }
1776
1777 static void test_enum_container(void)
1778 {
1779     BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
1780     DWORD dwBufferLen;
1781     BOOL result, fFound = FALSE;
1782
1783     /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1784      * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1785     SetLastError(0xdeadbeef);
1786     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1787     ok (result, "%08x\n", GetLastError());
1788     ok (dwBufferLen == MAX_PATH + 1 ||
1789         broken(dwBufferLen == 10) || /* Win9x, WinMe */
1790         broken(dwBufferLen == 55), /* NT4 */
1791         "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
1792
1793     /* If the result fits into abContainerName dwBufferLen is left untouched */
1794     dwBufferLen = (DWORD)sizeof(abContainerName);
1795     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1796     ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1797     
1798     /* We only check, if the currently open 'winetest' container is among the enumerated. */
1799     do {
1800         if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1801         dwBufferLen = (DWORD)sizeof(abContainerName);
1802     } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1803         
1804     ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1805 }
1806
1807 static BYTE signBlob[] = {
1808 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1809 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1810 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1811 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1812 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1813 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1814 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1815 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1816 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1817 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1818 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1819 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1820 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1821 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1822 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1823 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1824 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1825 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1826 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1827 0xb6,0x85,0x86,0x07 };
1828
1829 static void test_null_provider(void)
1830 {
1831     HCRYPTPROV prov;
1832     HCRYPTKEY key;
1833     BOOL result;
1834     DWORD keySpec, dataLen,dwParam;
1835     char szName[MAX_PATH];
1836
1837     result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1838     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1839      "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1840     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1841     ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
1842      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
1843     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1844      CRYPT_DELETEKEYSET);
1845     ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
1846      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
1847     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1848      CRYPT_DELETEKEYSET);
1849     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1850      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1851     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1852     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1853      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1854
1855     /* Delete the default container. */
1856     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1857     /* Once you've deleted the default container you can't open it as if it
1858      * already exists.
1859      */
1860     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1861     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1862      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1863     /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1864     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1865      CRYPT_VERIFYCONTEXT);
1866     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1867     if (!result) return;
1868     dataLen = sizeof(keySpec);
1869     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1870     if (result)
1871         ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1872          "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1873     /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1874      * supported, you can't get the keys from this container.
1875      */
1876     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1877     ok(!result && GetLastError() == NTE_NO_KEY,
1878      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1879     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1880     ok(!result && GetLastError() == NTE_NO_KEY,
1881      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1882     result = CryptReleaseContext(prov, 0);
1883     ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1884     /* You can create a new default container. */
1885     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1886      CRYPT_NEWKEYSET);
1887     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1888     /* But you still can't get the keys (until one's been generated.) */
1889     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1890     ok(!result && GetLastError() == NTE_NO_KEY,
1891      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1892     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1893     ok(!result && GetLastError() == NTE_NO_KEY,
1894      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1895     CryptReleaseContext(prov, 0);
1896     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1897
1898     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1899      CRYPT_DELETEKEYSET);
1900     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1901     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1902      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1903     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1904      CRYPT_VERIFYCONTEXT);
1905     ok(!result && GetLastError() == NTE_BAD_FLAGS,
1906      "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1907     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1908      CRYPT_NEWKEYSET);
1909     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1910     if (!result) return;
1911     /* Test provider parameters getter */
1912     dataLen = sizeof(dwParam);
1913     result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1914     ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1915         "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1916     dataLen = sizeof(dwParam);
1917     result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1918     ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1919         "Expected 0, got 0x%08X\n",dwParam);
1920     dataLen = sizeof(dwParam);
1921     result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1922     ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1923         "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1924     dataLen = sizeof(keySpec);
1925     SetLastError(0xdeadbeef);
1926     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1927     if (!result && GetLastError() == NTE_BAD_TYPE)
1928         skip("PP_KEYSPEC is not supported (win9x or NT)\n");
1929     else
1930         ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1931             "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1932     /* PP_CONTAINER parameter */
1933     dataLen = sizeof(szName);
1934     result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1935     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1936         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1937         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1938     /* PP_UNIQUE_CONTAINER parameter */
1939     dataLen = sizeof(szName);
1940     SetLastError(0xdeadbeef);
1941     result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1942     if (!result && GetLastError() == NTE_BAD_TYPE)
1943     {
1944         skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
1945     }
1946     else
1947     {
1948         char container[MAX_PATH];
1949
1950         ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
1951         uniquecontainer(container);
1952         todo_wine
1953         {
1954             ok(dataLen == strlen(container)+1, "Expected a param length of 70, got %d\n", dataLen);
1955             ok(!strcmp(container, szName), "Wrong container name : %s\n", szName);
1956         }
1957     }
1958     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1959     ok(!result && GetLastError() == NTE_NO_KEY,
1960      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1961     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1962     ok(!result && GetLastError() == NTE_NO_KEY,
1963      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1964
1965     /* Importing a key exchange blob.. */
1966     result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1967      0, 0, &key);
1968     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1969     CryptDestroyKey(key);
1970     /* allows access to the key exchange key.. */
1971     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1972     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1973     CryptDestroyKey(key);
1974     /* but not to the private key. */
1975     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1976     ok(!result && GetLastError() == NTE_NO_KEY,
1977      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1978     CryptReleaseContext(prov, 0);
1979     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1980      CRYPT_DELETEKEYSET);
1981
1982     /* Whereas importing a sign blob.. */
1983     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1984      CRYPT_NEWKEYSET);
1985     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1986     if (!result) return;
1987     result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1988     ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1989     CryptDestroyKey(key);
1990     /* doesn't allow access to the key exchange key.. */
1991     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1992     ok(!result && GetLastError() == NTE_NO_KEY,
1993      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1994     /* but does to the private key. */
1995     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1996     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1997     CryptDestroyKey(key);
1998     CryptReleaseContext(prov, 0);
1999
2000     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2001      CRYPT_DELETEKEYSET);
2002
2003
2004     /* test for the bug in accessing the user key in a container
2005      */
2006     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2007      CRYPT_NEWKEYSET);
2008     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2009     result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2010     ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2011     CryptDestroyKey(key);
2012     CryptReleaseContext(prov,0);
2013     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2014     ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2015     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2016     ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2017     CryptDestroyKey(key);
2018     CryptReleaseContext(prov, 0);
2019
2020     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2021      CRYPT_DELETEKEYSET);
2022
2023     /* test the machine key set */
2024     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2025      CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2026     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2027      CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2028     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2029     CryptReleaseContext(prov, 0);
2030     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2031      CRYPT_MACHINE_KEYSET);
2032     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2033     CryptReleaseContext(prov,0);
2034     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2035        CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2036     ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2037                 GetLastError());
2038     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2039      CRYPT_MACHINE_KEYSET);
2040     ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2041         "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2042
2043 }
2044
2045 START_TEST(rsaenh)
2046 {
2047     if (!init_base_environment())
2048         return;
2049     test_prov();
2050     test_gen_random();
2051     test_hashes();
2052     test_rc4();
2053     test_rc2();
2054     test_des();
2055     test_3des112();
2056     test_3des();
2057     test_hmac();
2058     test_mac();
2059     test_block_cipher_modes();
2060     test_import_private();
2061     test_verify_signature();
2062     test_rsa_encrypt();
2063     test_import_export();
2064     test_enum_container();
2065     clean_up_base_environment();
2066     test_schannel_provider();
2067     test_null_provider();
2068     if (!init_aes_environment())
2069         return;
2070     test_aes(128);
2071     test_aes(192);
2072     test_aes(256);
2073     clean_up_aes_environment();
2074 }