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