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