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