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