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