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