rsaenh: Disallow creating schannel master hashes before setting the client random...
[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 = CryptDestroyKey(hKeyExchangeKey);
666     ok(result, "CryptDestroyKey failed 0x%08x\n", GetLastError());
667     result = CryptDestroyHash(hHash);
668     ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
669     result = CryptReleaseContext(prov, 0);
670     ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
671 }
672
673 static void test_block_cipher_modes(void)
674 {
675     static const BYTE plain[23] = { 
676         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 
677         0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
678     static const BYTE ecb[24] = {   
679         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f, 
680         0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
681     static const BYTE cbc[24] = {   
682         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
683         0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
684     static const BYTE cfb[24] = {   
685         0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
686         0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
687     HCRYPTKEY hKey;
688     BOOL result;
689     BYTE abData[24];
690     DWORD dwMode, dwLen;
691
692     result = derive_key(CALG_RC2, &hKey, 40);
693     if (!result) return;
694
695     memcpy(abData, plain, sizeof(plain));
696
697     dwMode = CRYPT_MODE_ECB;
698     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
699     ok(result, "%08x\n", GetLastError());
700
701     result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
702     ok(result, "%08x\n", GetLastError());
703     ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
704
705     dwLen = 23;
706     result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
707     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
708     ok(dwLen == 24, "Unexpected length %d\n", dwLen);
709
710     SetLastError(ERROR_SUCCESS);
711     dwLen = 23;
712     result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
713     ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)), 
714        "%08x, dwLen: %d\n", GetLastError(), dwLen);
715
716     result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
717     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)), 
718        "%08x, dwLen: %d\n", GetLastError(), dwLen);
719
720     dwMode = CRYPT_MODE_CBC;
721     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
722     ok(result, "%08x\n", GetLastError());
723     
724     dwLen = 23;
725     result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
726     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
727     ok(dwLen == 24, "Unexpected length %d\n", dwLen);
728
729     dwLen = 23;
730     result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
731     ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)), 
732        "%08x, dwLen: %d\n", GetLastError(), dwLen);
733
734     result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
735     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)), 
736        "%08x, dwLen: %d\n", GetLastError(), dwLen);
737
738     dwMode = CRYPT_MODE_CFB;
739     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
740     ok(result, "%08x\n", GetLastError());
741     
742     dwLen = 16;
743     result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
744     ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
745
746     dwLen = 7;
747     result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
748     ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)), 
749        "%08x, dwLen: %d\n", GetLastError(), dwLen);
750     
751     dwLen = 8;
752     result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
753     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
754
755     dwLen = 16;
756     result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
757     ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)), 
758        "%08x, dwLen: %d\n", GetLastError(), dwLen);
759
760     dwMode = CRYPT_MODE_OFB;
761     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
762     ok(result, "%08x\n", GetLastError());
763     
764     dwLen = 23;
765     result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
766     ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
767
768     CryptDestroyKey(hKey);
769 }
770
771 static void test_3des112(void)
772 {
773     HCRYPTKEY hKey;
774     BOOL result;
775     DWORD dwLen;
776     unsigned char pbData[16];
777     int i;
778
779     result = derive_key(CALG_3DES_112, &hKey, 0);
780     if (!result) {
781         /* rsaenh compiled without OpenSSL */
782         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
783         return;
784     }
785
786     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
787     
788     dwLen = 13;
789     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
790     ok(result, "%08x\n", GetLastError());
791     
792     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
793     ok(result, "%08x\n", GetLastError());
794
795     for (i=0; i<4; i++)
796     {
797       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
798
799       dwLen = cTestData[i].enclen;
800       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
801       ok(result, "%08x\n", GetLastError());
802       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
803
804       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
805       ok(result, "%08x\n", GetLastError());
806       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
807       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
808       if((dwLen != cTestData[i].enclen) ||
809          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
810       {
811           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
812           printBytes("got",pbData,dwLen);
813       }
814     }
815     result = CryptDestroyKey(hKey);
816     ok(result, "%08x\n", GetLastError());
817 }
818
819 static void test_des(void) 
820 {
821     HCRYPTKEY hKey;
822     BOOL result;
823     DWORD dwLen, dwMode;
824     unsigned char pbData[16];
825     int i;
826
827     result = derive_key(CALG_DES, &hKey, 56);
828     if (!result) {
829         /* rsaenh compiled without OpenSSL */
830         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
831         return;
832     }
833
834     dwMode = CRYPT_MODE_ECB;
835     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
836     ok(result, "%08x\n", GetLastError());
837     
838     dwLen = sizeof(DWORD);
839     result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
840     ok(result, "%08x\n", GetLastError());
841     
842     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
843     
844     dwLen = 13;
845     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
846     ok(result, "%08x\n", GetLastError());
847     
848     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
849     ok(result, "%08x\n", GetLastError());
850
851     for (i=0; i<4; i++)
852     {
853       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
854
855       dwLen = cTestData[i].enclen;
856       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
857       ok(result, "%08x\n", GetLastError());
858       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
859
860       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
861       ok(result, "%08x\n", GetLastError());
862       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
863       ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
864       if((dwLen != cTestData[i].enclen) ||
865          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
866       {
867           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
868           printBytes("got",pbData,dwLen);
869       }
870     }
871
872     result = CryptDestroyKey(hKey);
873     ok(result, "%08x\n", GetLastError());
874 }
875
876 static void test_3des(void)
877 {
878     HCRYPTKEY hKey;
879     BOOL result;
880     DWORD dwLen;
881     unsigned char pbData[16];
882     static const BYTE des3[16] = { 
883         0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3, 
884         0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
885     int i;
886
887     result = derive_key(CALG_3DES, &hKey, 0);
888     if (!result) return;
889
890     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
891     
892     dwLen = 13;
893     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
894     ok(result, "%08x\n", GetLastError());
895
896     ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
897
898     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
899     ok(result, "%08x\n", GetLastError());
900
901     for (i=0; i<4; i++)
902     {
903       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
904
905       dwLen = cTestData[i].enclen;
906       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
907       ok(result, "%08x\n", GetLastError());
908       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
909
910       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
911       ok(result, "%08x\n", GetLastError());
912       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
913       ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
914       if((dwLen != cTestData[i].enclen) ||
915          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
916       {
917           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
918           printBytes("got",pbData,dwLen);
919       }
920     }
921     result = CryptDestroyKey(hKey);
922     ok(result, "%08x\n", GetLastError());
923 }
924
925 static void test_aes(int keylen)
926 {
927     HCRYPTKEY hKey;
928     BOOL result;
929     DWORD dwLen;
930     unsigned char pbData[16];
931     int i;
932
933     switch (keylen)
934     {
935         case 256:
936             result = derive_key(CALG_AES_256, &hKey, 0);
937             break;
938         case 192:
939             result = derive_key(CALG_AES_192, &hKey, 0);
940             break;
941         default:
942         case 128:
943             result = derive_key(CALG_AES_128, &hKey, 0);
944             break;
945     }
946     if (!result) return;
947
948     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
949
950     /* AES provider doesn't support salt */
951     result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
952     ok((!result && GetLastError() == NTE_BAD_KEY) || result /* Win7 */,
953        "expected NTE_BAD_KEY, got %08x\n", GetLastError());
954
955     dwLen = 13;
956     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
957     ok(result, "%08x\n", GetLastError());
958
959     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
960     ok(result, "%08x\n", GetLastError());
961
962     for (i=0; i<4; i++)
963     {
964       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
965
966       dwLen = cTestData[i].enclen;
967       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
968       ok(result, "%08x\n", GetLastError());
969       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
970
971       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
972       ok(result, "%08x\n", GetLastError());
973       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
974       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
975       if((dwLen != cTestData[i].enclen) ||
976          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
977       {
978           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
979           printBytes("got",pbData,dwLen);
980       }
981     }
982     result = CryptDestroyKey(hKey);
983     ok(result, "%08x\n", GetLastError());
984 }
985
986 static void test_sha2(void)
987 {
988     static const unsigned char sha256hash[32] = {
989         0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
990         0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
991         0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
992         0x1a, 0x08
993     };
994     static const unsigned char sha384hash[48] = {
995         0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
996         0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
997         0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
998         0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
999         0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
1000     };
1001     static const unsigned char sha512hash[64] = {
1002         0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1003         0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1004         0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1005         0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1006         0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1007         0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1008         0xb7, 0xf4, 0x81, 0xd4
1009     };
1010     unsigned char pbData[2048];
1011     BOOL result;
1012     HCRYPTHASH hHash;
1013     BYTE pbHashValue[64];
1014     DWORD hashlen, len;
1015     int i;
1016
1017     for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1018
1019     /* SHA-256 hash */
1020     SetLastError(0xdeadbeef);
1021     result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1022     if (!result && GetLastError() == NTE_BAD_ALGID) {
1023         win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1024         return;
1025     }
1026     ok(result, "%08x\n", GetLastError());
1027     if (result) {
1028         len = sizeof(DWORD);
1029         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1030         ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1031
1032         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1033         ok(result, "%08x\n", GetLastError());
1034
1035         len = 32;
1036         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1037         ok(result, "%08x\n", GetLastError());
1038
1039         ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1040
1041         result = CryptDestroyHash(hHash);
1042         ok(result, "%08x\n", GetLastError());
1043     }
1044
1045     /* SHA-384 hash */
1046     result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1047     ok(result, "%08x\n", GetLastError());
1048     if (result) {
1049         len = sizeof(DWORD);
1050         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1051         ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1052
1053         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1054         ok(result, "%08x\n", GetLastError());
1055
1056         len = 48;
1057         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1058         ok(result, "%08x\n", GetLastError());
1059
1060         ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1061
1062         result = CryptDestroyHash(hHash);
1063         ok(result, "%08x\n", GetLastError());
1064     }
1065
1066     /* SHA-512 hash */
1067     result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1068     ok(result, "%08x\n", GetLastError());
1069     if (result) {
1070         len = sizeof(DWORD);
1071         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1072         ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1073
1074         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1075         ok(result, "%08x\n", GetLastError());
1076
1077         len = 64;
1078         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1079         ok(result, "%08x\n", GetLastError());
1080
1081         ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1082
1083         result = CryptDestroyHash(hHash);
1084         ok(result, "%08x\n", GetLastError());
1085     }
1086 }
1087
1088 static void test_rc2(void)
1089 {
1090     static const BYTE rc2_40_encrypted[16] = {
1091         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1092         0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1093     static const BYTE rc2_128_encrypted[] = {
1094         0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
1095         0xb6,0x66 };
1096     HCRYPTHASH hHash;
1097     HCRYPTKEY hKey;
1098     BOOL result;
1099     DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
1100     BYTE *pbTemp;
1101     unsigned char pbData[2000], pbHashValue[16];
1102     int i;
1103     
1104     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1105
1106     /* MD2 Hashing */
1107     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1108     if (!result) {
1109         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1110     } else {
1111         CRYPT_INTEGER_BLOB salt;
1112
1113         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1114         ok(result, "%08x\n", GetLastError());
1115
1116         dwLen = 16;
1117         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1118         ok(result, "%08x\n", GetLastError());
1119
1120         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1121         ok(result, "%08x\n", GetLastError());
1122
1123         dwLen = sizeof(DWORD);
1124         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1125         ok(result, "%08x\n", GetLastError());
1126
1127         dwMode = CRYPT_MODE_CBC;
1128         result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1129         ok(result, "%08x\n", GetLastError());
1130
1131         dwLen = sizeof(DWORD);
1132         result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1133         ok(result, "%08x\n", GetLastError());
1134
1135         dwModeBits = 0xdeadbeef;
1136         dwLen = sizeof(DWORD);
1137         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1138         ok(result, "%08x\n", GetLastError());
1139         ok(dwModeBits ==
1140             (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1141             broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
1142             "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1143             " got %08x\n", dwModeBits);
1144
1145         dwLen = sizeof(DWORD);
1146         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1147         ok(result, "%08x\n", GetLastError());
1148
1149         dwLen = sizeof(DWORD);
1150         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1151         ok(result, "%08x\n", GetLastError());
1152
1153         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1154         ok(result, "%08x\n", GetLastError());
1155         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1156         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1157         HeapFree(GetProcessHeap(), 0, pbTemp);
1158
1159         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1160         ok(result, "%08x\n", GetLastError());
1161         /* The default salt length is always 11... */
1162         ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1163         /* and the default salt is always empty. */
1164         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1165         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1166         for (i=0; i<dwLen; i++)
1167             ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1168         HeapFree(GetProcessHeap(), 0, pbTemp);
1169
1170         dwLen = sizeof(DWORD);
1171         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1172
1173         result = CryptDestroyHash(hHash);
1174         ok(result, "%08x\n", GetLastError());
1175
1176         dwDataLen = 13;
1177         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1178         ok(result, "%08x\n", GetLastError());
1179
1180         ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1181
1182         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1183         ok(result, "%08x\n", GetLastError());
1184         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1185         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1186         HeapFree(GetProcessHeap(), 0, pbTemp);
1187
1188         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1189         ok(result, "%08x\n", GetLastError());
1190
1191         /* Setting the salt also succeeds... */
1192         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1193         ok(result, "setting salt failed: %08x\n", GetLastError());
1194         /* but the resulting salt length is now zero? */
1195         dwLen = 0;
1196         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1197         ok(result, "%08x\n", GetLastError());
1198         ok(dwLen == 0 ||
1199            broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1200            "unexpected salt length %d\n", dwLen);
1201         /* What sizes salt can I set? */
1202         salt.pbData = pbData;
1203         for (i=0; i<24; i++)
1204         {
1205             salt.cbData = i;
1206             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1207             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1208             /* The returned salt length is the same as the set salt length */
1209             result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1210             ok(result, "%08x\n", GetLastError());
1211             ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1212         }
1213         salt.cbData = 25;
1214         SetLastError(0xdeadbeef);
1215         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1216         ok(!result ||
1217            broken(result), /* Win9x, WinMe, NT4, W2K */
1218            "%08x\n", GetLastError());
1219
1220         result = CryptDestroyKey(hKey);
1221         ok(result, "%08x\n", GetLastError());
1222     }
1223
1224     /* Again, but test setting the effective key len */
1225     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1226
1227     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1228     if (!result) {
1229         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1230     } else {
1231         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1232         ok(result, "%08x\n", GetLastError());
1233
1234         dwLen = 16;
1235         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1236         ok(result, "%08x\n", GetLastError());
1237
1238         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1239         ok(result, "%08x\n", GetLastError());
1240
1241         SetLastError(0xdeadbeef);
1242         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1243         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1244         dwKeyLen = 0;
1245         SetLastError(0xdeadbeef);
1246         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1247         ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1248         dwKeyLen = 1025;
1249         SetLastError(0xdeadbeef);
1250         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1251         ok(!result, "CryptSetKeyParam failed: %08x\n", GetLastError());
1252
1253         dwLen = sizeof(dwKeyLen);
1254         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1255         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1256         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1257         ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1258
1259         dwKeyLen = 128;
1260         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1261         ok(result, "%d\n", GetLastError());
1262
1263         dwLen = sizeof(dwKeyLen);
1264         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1265         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1266         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1267         ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1268
1269         result = CryptDestroyHash(hHash);
1270         ok(result, "%08x\n", GetLastError());
1271
1272         dwDataLen = 13;
1273         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1274         ok(result, "%08x\n", GetLastError());
1275
1276         ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1277                 "RC2 encryption failed!\n");
1278
1279         /* Oddly enough this succeeds, though it should have no effect */
1280         dwKeyLen = 40;
1281         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1282         ok(result, "%d\n", GetLastError());
1283
1284         result = CryptDestroyKey(hKey);
1285         ok(result, "%08x\n", GetLastError());
1286     }
1287 }
1288
1289 static void test_rc4(void)
1290 {
1291     static const BYTE rc4[16] = { 
1292         0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0, 
1293         0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };    
1294     BOOL result;
1295     HCRYPTHASH hHash;
1296     HCRYPTKEY hKey;
1297     DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1298     unsigned char pbData[2000], *pbTemp;
1299     unsigned char pszBuffer[256];
1300     int i;
1301
1302     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1303
1304     /* MD2 Hashing */
1305     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1306     if (!result) {
1307         /* rsaenh compiled without OpenSSL */
1308         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1309     } else {
1310         CRYPT_INTEGER_BLOB salt;
1311
1312         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1313            ok(result, "%08x\n", GetLastError());
1314
1315         dwLen = 16;
1316         result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1317         ok(result, "%08x\n", GetLastError());
1318
1319         result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1320         ok(result, "%08x\n", GetLastError());
1321
1322         dwLen = sizeof(DWORD);
1323         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1324         ok(result, "%08x\n", GetLastError());
1325
1326         dwLen = sizeof(DWORD);
1327         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1328         ok(result, "%08x\n", GetLastError());
1329
1330         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1331         ok(result, "%08x\n", GetLastError());
1332         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1333         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1334         HeapFree(GetProcessHeap(), 0, pbTemp);
1335
1336         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1337         ok(result, "%08x\n", GetLastError());
1338         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1339         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1340         HeapFree(GetProcessHeap(), 0, pbTemp);
1341
1342         dwLen = sizeof(DWORD);
1343         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1344
1345         result = CryptDestroyHash(hHash);
1346         ok(result, "%08x\n", GetLastError());
1347
1348         dwDataLen = 16;
1349         result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1350         ok(result, "%08x\n", GetLastError());
1351         dwDataLen = 16;
1352         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1353         ok(result, "%08x\n", GetLastError());
1354
1355         ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1356
1357         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1358         ok(result, "%08x\n", GetLastError());
1359
1360         /* Setting the salt also succeeds... */
1361         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1362         ok(result, "setting salt failed: %08x\n", GetLastError());
1363         /* but the resulting salt length is now zero? */
1364         dwLen = 0;
1365         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1366         ok(result, "%08x\n", GetLastError());
1367         ok(dwLen == 0 ||
1368            broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1369            "unexpected salt length %d\n", dwLen);
1370         /* What sizes salt can I set? */
1371         salt.pbData = pbData;
1372         for (i=0; i<24; i++)
1373         {
1374             salt.cbData = i;
1375             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1376             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1377             /* The returned salt length is the same as the set salt length */
1378             result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1379             ok(result, "%08x\n", GetLastError());
1380             ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1381         }
1382         salt.cbData = 25;
1383         SetLastError(0xdeadbeef);
1384         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1385         ok(!result ||
1386            broken(result), /* Win9x, WinMe, NT4, W2K */
1387            "%08x\n", GetLastError());
1388
1389         result = CryptDestroyKey(hKey);
1390         ok(result, "%08x\n", GetLastError());
1391     }
1392 }
1393
1394 static void test_hmac(void) {
1395     HCRYPTKEY hKey;
1396     HCRYPTHASH hHash;
1397     BOOL result;
1398     /* Using CALG_MD2 here fails on Windows 2003, why ? */
1399     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1400     DWORD dwLen;
1401     BYTE abData[256];
1402     static const BYTE hmac[16] = { 
1403         0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c, 
1404         0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1405     int i;
1406
1407     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1408
1409     if (!derive_key(CALG_RC2, &hKey, 56)) return;
1410
1411     result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1412     ok(result, "%08x\n", GetLastError());
1413     if (!result) return;
1414
1415     result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1416     ok(result, "%08x\n", GetLastError());
1417
1418     result = CryptHashData(hHash, abData, sizeof(abData), 0);
1419     ok(result, "%08x\n", GetLastError());
1420
1421     dwLen = sizeof(abData)/sizeof(BYTE);
1422     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1423     ok(result, "%08x\n", GetLastError());
1424
1425     ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1426     
1427     result = CryptDestroyHash(hHash);
1428     ok(result, "%08x\n", GetLastError());
1429     
1430     result = CryptDestroyKey(hKey);
1431     ok(result, "%08x\n", GetLastError());
1432
1433     /* Provoke errors */
1434     result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1435     ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1436 }
1437
1438 static void test_mac(void) {
1439     HCRYPTKEY hKey;
1440     HCRYPTHASH hHash;
1441     BOOL result;
1442     DWORD dwLen;
1443     BYTE abData[256], abEnc[264];
1444     static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1445     int i;
1446
1447     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1448     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1449
1450     if (!derive_key(CALG_RC2, &hKey, 40)) return;
1451
1452     dwLen = 256;
1453     result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1454     ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1455     
1456     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1457     ok(result, "%08x\n", GetLastError());
1458     if (!result) return;
1459
1460     result = CryptHashData(hHash, abData, sizeof(abData), 0);
1461     ok(result, "%08x\n", GetLastError());
1462
1463     dwLen = sizeof(abData)/sizeof(BYTE);
1464     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1465     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1466
1467     ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1468     
1469     result = CryptDestroyHash(hHash);
1470     ok(result, "%08x\n", GetLastError());
1471     
1472     result = CryptDestroyKey(hKey);
1473     ok(result, "%08x\n", GetLastError());
1474     
1475     /* Provoke errors */
1476     if (!derive_key(CALG_RC4, &hKey, 56)) return;
1477
1478     SetLastError(0xdeadbeef);
1479     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1480     ok((!result && GetLastError() == NTE_BAD_KEY) ||
1481             broken(result), /* Win9x, WinMe, NT4, W2K */
1482             "%08x\n", GetLastError());
1483
1484     result = CryptDestroyKey(hKey);
1485     ok(result, "%08x\n", GetLastError());
1486 }
1487
1488 static void test_import_private(void) 
1489 {
1490     DWORD dwLen, dwVal;
1491     HCRYPTKEY hKeyExchangeKey, hSessionKey;
1492     BOOL result;
1493     static BYTE abSessionKey[148] = {
1494         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1495         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1496         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1497         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1498         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1499         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1500         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1501         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1502         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1503         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1504         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1505         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1506         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1507         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1508         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1509         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1510         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1511         0x04, 0x8c, 0x49, 0x92
1512     };
1513     static BYTE abEncryptedMessage[12] = {
1514         0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1515         0x1c, 0xfd, 0xde, 0x71
1516     };
1517             
1518     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1519     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1520     if (!result) {
1521         /* rsaenh compiled without OpenSSL */
1522         ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1523         return;
1524     }
1525
1526     dwLen = (DWORD)sizeof(abSessionKey);
1527     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1528     ok(result, "%08x\n", GetLastError());
1529     if (!result) return;
1530
1531     dwVal = 0xdeadbeef;
1532     dwLen = sizeof(DWORD);
1533     result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1534     ok(result, "%08x\n", GetLastError());
1535     ok(dwVal ==
1536         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1537         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1538         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1539         " got %08x\n", dwVal);
1540
1541     dwLen = (DWORD)sizeof(abEncryptedMessage);
1542     result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1543     ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12), 
1544        "%08x, len: %d\n", GetLastError(), dwLen);
1545     CryptDestroyKey(hSessionKey);
1546     
1547     if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1548
1549     dwLen = (DWORD)sizeof(abSessionKey);
1550     result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1551     ok(result, "%08x\n", GetLastError());
1552     CryptDestroyKey(hSessionKey);
1553     if (!result) return;
1554
1555     dwLen = (DWORD)sizeof(abSessionKey);
1556     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1557     ok(result, "%08x\n", GetLastError());
1558     if (!result) return;
1559
1560     CryptDestroyKey(hSessionKey);
1561     CryptDestroyKey(hKeyExchangeKey);
1562 }
1563
1564 static void test_verify_signature(void) {
1565     HCRYPTHASH hHash;
1566     HCRYPTKEY hPubSignKey;
1567     BYTE abData[] = "Wine rocks!";
1568     BOOL result;
1569     BYTE abPubKey[148] = {
1570         0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 
1571         0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 
1572         0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19, 
1573         0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27, 
1574         0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8, 
1575         0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda, 
1576         0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a, 
1577         0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc, 
1578         0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c, 
1579         0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c, 
1580         0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89, 
1581         0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b, 
1582         0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa, 
1583         0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63, 
1584         0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff, 
1585         0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49, 
1586         0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87, 
1587         0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7, 
1588         0xe1, 0x21, 0x50, 0xac
1589     };
1590     /* md2 with hash oid */
1591     BYTE abSignatureMD2[128] = {
1592         0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67, 
1593         0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b, 
1594         0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda, 
1595         0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59, 
1596         0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a, 
1597         0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34, 
1598         0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40, 
1599         0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7, 
1600         0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0, 
1601         0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06, 
1602         0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51, 
1603         0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f, 
1604         0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46, 
1605         0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25, 
1606         0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0, 
1607         0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1608     };
1609     /* md2 without hash oid */
1610     BYTE abSignatureMD2NoOID[128] = {
1611         0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d, 
1612         0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19, 
1613         0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd, 
1614         0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4, 
1615         0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65, 
1616         0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99, 
1617         0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf, 
1618         0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc, 
1619         0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0, 
1620         0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01, 
1621         0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7, 
1622         0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f, 
1623         0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a, 
1624         0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9, 
1625         0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06, 
1626         0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1627     };
1628     /* md4 with hash oid */
1629     BYTE abSignatureMD4[128] = {
1630         0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51, 
1631         0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b, 
1632         0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2, 
1633         0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e, 
1634         0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13, 
1635         0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9, 
1636         0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f, 
1637         0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96, 
1638         0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9, 
1639         0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e, 
1640         0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0, 
1641         0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe, 
1642         0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18, 
1643         0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab, 
1644         0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3, 
1645         0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1646     };
1647     /* md4 without hash oid */
1648     BYTE abSignatureMD4NoOID[128] = {
1649         0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda, 
1650         0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24, 
1651         0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0, 
1652         0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36, 
1653         0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85, 
1654         0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3, 
1655         0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f, 
1656         0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9, 
1657         0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06, 
1658         0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f, 
1659         0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb, 
1660         0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96, 
1661         0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f, 
1662         0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9, 
1663         0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb, 
1664         0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1665     }; 
1666     /* md5 with hash oid */
1667     BYTE abSignatureMD5[128] = {
1668         0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5, 
1669         0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f, 
1670         0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7, 
1671         0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98, 
1672         0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec, 
1673         0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5, 
1674         0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04, 
1675         0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b, 
1676         0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95, 
1677         0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c, 
1678         0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29, 
1679         0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9, 
1680         0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c, 
1681         0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90, 
1682         0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e, 
1683         0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1684     };
1685     /* md5 without hash oid */
1686     BYTE abSignatureMD5NoOID[128] = {
1687         0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f, 
1688         0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75, 
1689         0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f, 
1690         0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d, 
1691         0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f, 
1692         0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49, 
1693         0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8, 
1694         0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c, 
1695         0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23, 
1696         0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19, 
1697         0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb, 
1698         0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3, 
1699         0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b, 
1700         0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b, 
1701         0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5, 
1702         0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1703     };
1704     /* sha with hash oid */
1705     BYTE abSignatureSHA[128] = {
1706         0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91, 
1707         0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd, 
1708         0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24, 
1709         0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94, 
1710         0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f, 
1711         0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a, 
1712         0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52, 
1713         0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20, 
1714         0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5, 
1715         0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a, 
1716         0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff, 
1717         0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53, 
1718         0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00, 
1719         0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e, 
1720         0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98, 
1721         0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1722     };
1723     /* sha without hash oid */
1724     BYTE abSignatureSHANoOID[128] = {
1725         0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6, 
1726         0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a, 
1727         0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f, 
1728         0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37, 
1729         0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65, 
1730         0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe, 
1731         0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6, 
1732         0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe, 
1733         0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c, 
1734         0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4, 
1735         0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80, 
1736         0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a, 
1737         0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00, 
1738         0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd, 
1739         0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67, 
1740         0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1741     }; 
1742     
1743     result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1744     ok(result, "%08x\n", GetLastError());
1745     if (!result) return;
1746
1747     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1748     ok(result, "%08x\n", GetLastError());
1749     if (!result) return;
1750
1751     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1752     ok(result, "%08x\n", GetLastError());
1753     if (!result) return;
1754
1755     /*check that a NULL pointer signature is correctly handled*/
1756     result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1757     ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1758      "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1759     if (result) return;
1760
1761     /* check that we get a bad signature error when the signature is too short*/
1762     SetLastError(0xdeadbeef);
1763     result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1764     ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1765      broken(result), /* Win9x, WinMe, NT4 */
1766      "Expected NTE_BAD_SIGNATURE, got %08x\n",  GetLastError());
1767
1768     result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1769     ok(result, "%08x\n", GetLastError());
1770     if (!result) return;
1771
1772     result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1773     ok(result, "%08x\n", GetLastError());
1774     if (!result) return;
1775
1776     /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about 
1777      * the OID at all. */
1778     /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1779     ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1780     if (result) return;*/
1781
1782     CryptDestroyHash(hHash);
1783
1784     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1785     ok(result, "%08x\n", GetLastError());
1786     if (!result) return;
1787
1788     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1789     ok(result, "%08x\n", GetLastError());
1790     if (!result) return;
1791
1792     result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1793     ok(result, "%08x\n", GetLastError());
1794     if (!result) return;
1795
1796     result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1797     ok(result, "%08x\n", GetLastError());
1798     if (!result) return;
1799
1800     CryptDestroyHash(hHash);
1801
1802     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1803     ok(result, "%08x\n", GetLastError());
1804     if (!result) return;
1805
1806     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1807     ok(result, "%08x\n", GetLastError());
1808     if (!result) return;
1809
1810     result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1811     ok(result, "%08x\n", GetLastError());
1812     if (!result) return;
1813
1814     result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1815     ok(result, "%08x\n", GetLastError());
1816     if (!result) return;
1817
1818     CryptDestroyHash(hHash);
1819
1820     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1821     ok(result, "%08x\n", GetLastError());
1822     if (!result) return;
1823
1824     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1825     ok(result, "%08x\n", GetLastError());
1826     if (!result) return;
1827
1828     result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1829     ok(result, "%08x\n", GetLastError());
1830     if (!result) return;
1831
1832     result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1833     ok(result, "%08x\n", GetLastError());
1834     if (!result) return;
1835
1836     CryptDestroyHash(hHash);
1837     CryptDestroyKey(hPubSignKey);
1838 }
1839
1840 static void test_rsa_encrypt(void)
1841 {
1842     HCRYPTKEY hRSAKey;
1843     BYTE abData[2048] = "Wine rocks!";
1844     BOOL result;
1845     DWORD dwVal, dwLen;
1846
1847     /* It is allowed to use the key exchange key for encryption/decryption */
1848     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1849     ok (result, "%08x\n", GetLastError());
1850     if (!result) return;
1851
1852     dwLen = 12;
1853     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1854     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1855     ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1856     dwLen = 12;
1857     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1858     ok (result, "%08x\n", GetLastError());
1859     if (!result) return;
1860
1861     result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1862     ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1863     
1864     dwVal = 0xdeadbeef;
1865     dwLen = sizeof(DWORD);
1866     result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1867     ok(result, "%08x\n", GetLastError());
1868     ok(dwVal ==
1869         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1870         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1871         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1872         " got %08x\n", dwVal);
1873
1874     /* An RSA key doesn't support salt */
1875     result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1876     ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
1877        "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
1878
1879     /* The key exchange key's public key may be exported.. */
1880     result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1881     ok(result, "%08x\n", GetLastError());
1882     /* but its private key may not be. */
1883     SetLastError(0xdeadbeef);
1884     result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1885     ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1886         broken(result), /* Win9x/NT4 */
1887         "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1888     /* Setting the permissions of the key exchange key isn't allowed, either. */
1889     dwVal |= CRYPT_EXPORT;
1890     SetLastError(0xdeadbeef);
1891     result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1892     ok(!result &&
1893         (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1894         "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1895
1896     CryptDestroyKey(hRSAKey);
1897
1898     /* It is not allowed to use the signature key for encryption/decryption */
1899     result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1900     ok (result, "%08x\n", GetLastError());
1901     if (!result) return;
1902
1903     dwVal = 0xdeadbeef;
1904     dwLen = sizeof(DWORD);
1905     result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1906     ok(result, "%08x\n", GetLastError());
1907     ok(dwVal ==
1908         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1909         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1910         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1911         " got %08x\n", dwVal);
1912
1913     /* The signature key's public key may also be exported.. */
1914     result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1915     ok(result, "%08x\n", GetLastError());
1916     /* but its private key may not be. */
1917     SetLastError(0xdeadbeef);
1918     result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1919     ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1920         broken(result), /* Win9x/NT4 */
1921         "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1922     /* Setting the permissions of the signature key isn't allowed, either. */
1923     dwVal |= CRYPT_EXPORT;
1924     SetLastError(0xdeadbeef);
1925     result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1926     ok(!result &&
1927         (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1928         "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1929
1930     dwLen = 12;
1931     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1932     ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1933
1934     CryptDestroyKey(hRSAKey);
1935 }
1936
1937 static void test_import_export(void)
1938 {
1939     DWORD dwLen, dwDataLen, dwVal;
1940     HCRYPTKEY hPublicKey, hPrivKey;
1941     BOOL result;
1942     ALG_ID algID;
1943     BYTE emptyKey[2048], *exported_key;
1944     static BYTE abPlainPublicKey[84] = {
1945         0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1946         0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1947         0x01, 0x00, 0x01, 0x00, 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, 0x11, 0x11, 0x11, 0x11,
1953         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1954         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1955         0x11, 0x11, 0x11, 0x11
1956     };
1957     static BYTE priv_key_with_high_bit[] = {
1958         0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1959         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1960         0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1961         0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1962         0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1963         0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1964         0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1965         0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1966         0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1967         0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1968         0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1969         0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1970         0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1971         0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1972         0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1973         0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1974         0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1975         0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1976         0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1977         0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1978         0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1979         0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1980         0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1981         0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1982         0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1983         0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1984         0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1985         0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1986         0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1987         0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1988         0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1989         0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1990         0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1991         0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1992         0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1993         0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1994         0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1995         0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1996         0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1997         0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1998         0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1999         0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2000         0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2001         0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2002         0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2003         0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2004         0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2005         0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2006         0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2007         0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2008         0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2009         0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2010         0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2011         0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2012         0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2013         0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2014         0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2015         0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2016         0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2017         0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2018         0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2019         0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2020         0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2021         0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2022         0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2023         0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2024         0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2025         0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2026         0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2027         0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2028         0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2029         0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2030         0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2031         0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2032         0xb6, 0x5f, 0x01, 0x5e
2033     };
2034     static const BYTE expected_exported_priv_key[] = {
2035         0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2036         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2037         0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2038         0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2039         0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2040         0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2041         0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2042         0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2043         0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2044         0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2045         0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2046         0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2047         0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2048         0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2049         0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2050         0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2051         0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2052         0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2053         0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2054         0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2055         0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2056         0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2057         0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2058         0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2059         0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2060         0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2061         0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2062         0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2063         0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2064         0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2065         0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2066         0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2067         0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2068         0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2069         0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2070         0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2071         0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2072         0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2073         0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2074         0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2075         0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2076         0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2077         0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2078         0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2079         0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2080         0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2081         0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2082         0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2083         0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2084         0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2085         0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2086         0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2087         0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2088         0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2089         0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2090         0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2091         0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2092         0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2093         0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2094         0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2095         0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2096         0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2097         0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2098         0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2099         0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2100         0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2101         0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2102         0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2103         0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2104         0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2105         0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2106         0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2107         0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2108         0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2109         0xb6, 0x5f, 0x01, 0x5e
2110     };
2111
2112     dwLen=84;
2113     result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2114     ok(result, "failed to import the public key\n");
2115
2116     dwDataLen=sizeof(algID);
2117     result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2118     ok(result, "failed to get the KP_ALGID from the imported public key\n");
2119     ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2120         
2121     dwVal = 0xdeadbeef;
2122     dwDataLen = sizeof(DWORD);
2123     result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2124     ok(result, "%08x\n", GetLastError());
2125     ok(dwVal ==
2126         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2127         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2128         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2129         " got %08x\n", dwVal);
2130     result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2131     ok(result, "failed to export the fresh imported public key\n");
2132     ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2133     ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2134
2135     CryptDestroyKey(hPublicKey);
2136
2137     result = CryptImportKey(hProv, priv_key_with_high_bit,
2138         sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2139     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2140
2141     result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2142     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2143     exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2144     result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2145         &dwDataLen);
2146     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2147
2148     ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2149         dwDataLen);
2150     ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2151         "unexpected value\n");
2152
2153     HeapFree(GetProcessHeap(), 0, exported_key);
2154
2155     CryptDestroyKey(hPrivKey);
2156 }
2157
2158 static void test_import_hmac(void)
2159 {
2160     /* Test cases from RFC 2202, section 3 */
2161     static const struct rfc2202_test_case {
2162         const char *key;
2163         DWORD key_len;
2164         const char *data;
2165         const DWORD data_len;
2166         const char *digest;
2167     } cases[] = {
2168         { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2169           "\x0b\x0b\x0b\x0b", 20,
2170           "Hi There", 8,
2171           "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2172           "\xf1\x46\xbe\x00" },
2173         { "Jefe", 4,
2174           "what do ya want for nothing?", 28,
2175           "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2176           "\x25\x9a\x7c\x79" },
2177         { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2178           "\xaa\xaa\xaa\xaa", 20,
2179           "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2180           "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2181           "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2182           "\xdd\xdd", 50,
2183           "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2184           "\x63\xf1\x75\xd3" },
2185         { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2186           "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2187           "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2188           "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2189           "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2190           "\xcd\xcd", 50,
2191           "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2192           "\x2d\x72\x35\xda" },
2193         { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2194           "\x0c\x0c\x0c\x0c", 20,
2195           "Test With Truncation", 20,
2196           "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2197           "\x4a\x9a\x5a\x04" },
2198         { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2199           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2200           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2201           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2202           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2203           80,
2204           "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2205           "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2206           "\xed\x40\x21\x12" },
2207         { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2208           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2209           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2210           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2211           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2212           80,
2213           "Test Using Larger Than Block-Size Key and Larger "
2214           "Than One Block-Size Data", 73,
2215           "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2216           "\xbb\xff\x1a\x91" }
2217     };
2218     DWORD i;
2219
2220     for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++)
2221     {
2222         const struct rfc2202_test_case *test_case = &cases[i];
2223         DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2224         BYTE *blob = HeapAlloc(GetProcessHeap(), 0, size);
2225
2226         if (blob)
2227         {
2228             BLOBHEADER *header = (BLOBHEADER *)blob;
2229             DWORD *key_len = (DWORD *)(header + 1);
2230             BYTE *key_bytes = (BYTE *)(key_len + 1);
2231             BOOL result;
2232             HCRYPTKEY key;
2233
2234             header->bType = PLAINTEXTKEYBLOB;
2235             header->bVersion = CUR_BLOB_VERSION;
2236             header->reserved = 0;
2237             header->aiKeyAlg = CALG_RC2;
2238             *key_len = test_case->key_len;
2239             memcpy(key_bytes, test_case->key, *key_len);
2240             result = CryptImportKey(hProv, blob, size, 0, CRYPT_IPSEC_HMAC_KEY, &key);
2241             ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
2242             if (result)
2243             {
2244                 HCRYPTHASH hash;
2245                 HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2246                 BYTE digest[20];
2247                 DWORD digest_size;
2248
2249                 result = CryptCreateHash(hProv, CALG_HMAC, key, 0, &hash);
2250                 ok(result, "CryptCreateHash failed on test case %d: %08x\n", i, GetLastError());
2251                 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2252                 ok(result, "CryptSetHashParam failed on test case %d: %08x\n", i, GetLastError());
2253                 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2254                 ok(result, "CryptHashData failed on test case %d: %08x\n", i, GetLastError());
2255                 digest_size = sizeof(digest);
2256                 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2257                 ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
2258                 ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected value on test case %d\n", i);
2259                 CryptDestroyHash(hash);
2260                 CryptDestroyKey(key);
2261             }
2262             HeapFree(GetProcessHeap(), 0, blob);
2263         }
2264     }
2265 }
2266         
2267 static void test_schannel_provider(void)
2268 {
2269     HCRYPTPROV hProv;
2270     HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2271     HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2272     BOOL result;
2273     DWORD dwLen;
2274     SCHANNEL_ALG saSChannelAlg;
2275     CRYPT_DATA_BLOB data_blob;
2276     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2277     BYTE abTLS1Master[140] = {
2278         0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00, 
2279         0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68, 
2280         0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97, 
2281         0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53, 
2282         0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24, 
2283         0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3, 
2284         0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8, 
2285         0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d, 
2286         0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e, 
2287         0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e, 
2288         0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40, 
2289         0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b, 
2290         0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb, 
2291         0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6, 
2292         0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac, 
2293         0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41, 
2294         0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4, 
2295         0xd3, 0x1e, 0x82, 0xb3
2296     };
2297     BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2298     BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2299     BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2300     BYTE abClientFinished[16] = "client finished";
2301     BYTE abData[16] = "Wine rocks!";
2302     BYTE abMD5Hash[16];
2303     static const BYTE abEncryptedData[16] = {
2304         0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2305         0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d    
2306     };
2307     static const BYTE abPRF[16] = {
2308         0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2309         0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2310     };
2311     static const BYTE abMD5[16] = {
2312         0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2313         0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2314     };
2315     
2316     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2317     if (!result)
2318     {
2319         win_skip("no PROV_RSA_SCHANNEL support\n");
2320         return;
2321     }
2322     ok (result, "%08x\n", GetLastError());
2323     if (result)
2324         CryptReleaseContext(hProv, 0);
2325
2326     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2327     ok (result, "%08x\n", GetLastError());
2328     if (!result) return;
2329     
2330     /* To get deterministic results, we import the TLS1 master secret (which
2331      * is typically generated from a random generator). Therefore, we need
2332      * an RSA key. */
2333     dwLen = (DWORD)sizeof(abPlainPrivateKey);
2334     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2335     ok (result, "%08x\n", GetLastError());
2336     if (!result) return;
2337
2338     dwLen = (DWORD)sizeof(abTLS1Master);
2339     result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2340     ok (result, "%08x\n", GetLastError());
2341     if (!result) return;    
2342
2343     /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2344      * (Keys can only be derived from hashes, not from other keys.)
2345      * The hash can't be created yet because the key doesn't have the client
2346      * random or server random set.
2347      */
2348     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2349     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER,
2350         "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2351
2352     /* Setting the TLS1 client and server random parameters, as well as the 
2353      * MAC and encryption algorithm parameters. */
2354     data_blob.cbData = 33;
2355     data_blob.pbData = abClientSecret;
2356     result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2357     ok (result, "%08x\n", GetLastError());
2358     if (!result) return;
2359
2360     data_blob.cbData = 33;
2361     data_blob.pbData = abServerSecret;
2362     result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2363     ok (result, "%08x\n", GetLastError());
2364     if (!result) return;
2365
2366     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2367     ok (result, "%08x\n", GetLastError());
2368     if (!result) return;
2369
2370     /* Deriving the server write encryption key from the master hash can't
2371      * succeed before the encryption key algorithm is set.
2372      */
2373     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2374     todo_wine
2375     ok (!result && GetLastError() == NTE_BAD_FLAGS,
2376         "expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2377
2378     CryptDestroyHash(hMasterHash);
2379
2380     saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2381     saSChannelAlg.Algid = CALG_DES;
2382     saSChannelAlg.cBits = 64;
2383     saSChannelAlg.dwFlags = 0;
2384     saSChannelAlg.dwReserved = 0;
2385     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2386     ok (result, "%08x\n", GetLastError());
2387     if (!result) return;
2388
2389     saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2390     saSChannelAlg.Algid = CALG_MD5;
2391     saSChannelAlg.cBits = 128;
2392     saSChannelAlg.dwFlags = 0;
2393     saSChannelAlg.dwReserved = 0;
2394     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2395     ok (result, "%08x\n", GetLastError());
2396     if (!result) return;
2397
2398     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2399     ok (result, "%08x\n", GetLastError());
2400     if (!result) return;
2401
2402     /* Deriving the server write encryption key from the master hash */
2403     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2404     ok (result, "%08x\n", GetLastError());
2405     if (!result) return;
2406
2407     /* Encrypting some data with the server write encryption key and checking the result. */
2408     dwLen = 12;
2409     result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2410     ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2411
2412     /* Second test case: Test the TLS1 pseudo random number function. */
2413     result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2414     ok (result, "%08x\n", GetLastError());
2415     if (!result) return;
2416
2417     /* Set the label and seed parameters for the random number function */
2418     data_blob.cbData = 36;
2419     data_blob.pbData = abHashedHandshakes;
2420     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2421     ok (result, "%08x\n", GetLastError());
2422     if (!result) return;
2423
2424     data_blob.cbData = 15;
2425     data_blob.pbData = abClientFinished;
2426     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2427     ok (result, "%08x\n", GetLastError());
2428     if (!result) return;
2429
2430     /* Generate some pseudo random bytes and check if they are correct. */
2431     dwLen = (DWORD)sizeof(abData);
2432     result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2433     ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)), 
2434         "%08x\n", GetLastError());
2435
2436     /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2437      * Hash some data with the HMAC. Compare results. */
2438     result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2439     ok (result, "%08x\n", GetLastError());
2440     if (!result) return;
2441     
2442     result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2443     ok (result, "%08x\n", GetLastError());
2444     if (!result) return;
2445
2446     result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2447     ok (result, "%08x\n", GetLastError());
2448     if (!result) return;
2449
2450     result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2451     ok (result, "%08x\n", GetLastError());
2452     if (!result) return;
2453
2454     dwLen = (DWORD)sizeof(abMD5Hash);
2455     result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2456     ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2457
2458     CryptDestroyHash(hHMAC);
2459     CryptDestroyHash(hTLS1PRF);
2460     CryptDestroyHash(hMasterHash);
2461     CryptDestroyKey(hServerWriteMACKey);
2462     CryptDestroyKey(hServerWriteKey);
2463     CryptDestroyKey(hRSAKey);
2464     CryptDestroyKey(hMasterSecret);
2465     CryptReleaseContext(hProv, 0);
2466     CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2467 }
2468
2469 /* Test that a key can be used to encrypt data and exported, and that, when
2470  * the exported key is imported again, can be used to decrypt the original
2471  * data again.
2472  */
2473 static void test_rsa_round_trip(void)
2474 {
2475     static const char test_string[] = "Well this is a fine how-do-you-do.";
2476     HCRYPTPROV prov;
2477     HCRYPTKEY signKey, keyExchangeKey;
2478     BOOL result;
2479     BYTE data[256], *exportedKey;
2480     DWORD dataLen, keyLen;
2481
2482     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2483      CRYPT_DELETEKEYSET);
2484
2485     /* Generate a new key... */
2486     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2487      CRYPT_NEWKEYSET);
2488     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2489     result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2490     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2491     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2492     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2493     /* encrypt some data with it... */
2494     memcpy(data, test_string, strlen(test_string) + 1);
2495     dataLen = strlen(test_string) + 1;
2496     result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2497                           sizeof(data));
2498     ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2499        broken(GetLastError() == NTE_PERM /* NT4 */),
2500        "CryptEncrypt failed: %08x\n", GetLastError());
2501     /* export the key... */
2502     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2503                             &keyLen);
2504     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2505     exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2506     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2507                             &keyLen);
2508     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2509     /* destroy the key... */
2510     CryptDestroyKey(keyExchangeKey);
2511     CryptDestroyKey(signKey);
2512     /* import the key again... */
2513     result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2514     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2515     HeapFree(GetProcessHeap(), 0, exportedKey);
2516     /* and decrypt the data encrypted with the original key with the imported
2517      * key.
2518      */
2519     result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2520     ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2521        broken(GetLastError() == NTE_PERM /* NT4 */),
2522        "CryptDecrypt failed: %08x\n", GetLastError());
2523     if (result)
2524     {
2525         ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2526         ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2527     }
2528     CryptDestroyKey(keyExchangeKey);
2529     CryptReleaseContext(prov, 0);
2530
2531     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2532      CRYPT_DELETEKEYSET);
2533 }
2534
2535 static void test_enum_container(void)
2536 {
2537     BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2538     DWORD dwBufferLen;
2539     BOOL result, fFound = FALSE;
2540
2541     /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2542      * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2543     SetLastError(0xdeadbeef);
2544     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2545     ok (result, "%08x\n", GetLastError());
2546     ok (dwBufferLen == MAX_PATH + 1 ||
2547         broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2548         "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2549
2550     /* If the result fits into abContainerName dwBufferLen is left untouched */
2551     dwBufferLen = (DWORD)sizeof(abContainerName);
2552     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2553     ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2554     
2555     /* We only check, if the currently open 'winetest' container is among the enumerated. */
2556     do {
2557         if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2558         dwBufferLen = (DWORD)sizeof(abContainerName);
2559     } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2560         
2561     ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2562 }
2563
2564 static BYTE signBlob[] = {
2565 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2566 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2567 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2568 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2569 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2570 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2571 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2572 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2573 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2574 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2575 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2576 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2577 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2578 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2579 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2580 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2581 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2582 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2583 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2584 0xb6,0x85,0x86,0x07 };
2585
2586 static void test_null_provider(void)
2587 {
2588     HCRYPTPROV prov;
2589     HCRYPTKEY key;
2590     BOOL result;
2591     DWORD keySpec, dataLen,dwParam;
2592     char szName[MAX_PATH];
2593
2594     result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2595     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2596      "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2597     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2598     ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2599      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2600     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2601      CRYPT_DELETEKEYSET);
2602     ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2603      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2604     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2605      CRYPT_DELETEKEYSET);
2606     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2607      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2608     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2609     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2610      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2611
2612     /* Delete the default container. */
2613     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2614     /* Once you've deleted the default container you can't open it as if it
2615      * already exists.
2616      */
2617     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2618     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2619      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2620     /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2621     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2622      CRYPT_VERIFYCONTEXT);
2623     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2624     if (!result) return;
2625     dataLen = sizeof(keySpec);
2626     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2627     if (result)
2628         ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2629          "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2630     /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2631      * supported, you can't get the keys from this container.
2632      */
2633     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2634     ok(!result && GetLastError() == NTE_NO_KEY,
2635      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2636     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2637     ok(!result && GetLastError() == NTE_NO_KEY,
2638      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2639     result = CryptReleaseContext(prov, 0);
2640     ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2641     /* You can create a new default container. */
2642     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2643      CRYPT_NEWKEYSET);
2644     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2645     /* But you still can't get the keys (until one's been generated.) */
2646     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2647     ok(!result && GetLastError() == NTE_NO_KEY,
2648      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2649     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2650     ok(!result && GetLastError() == NTE_NO_KEY,
2651      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2652     CryptReleaseContext(prov, 0);
2653     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2654
2655     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2656      CRYPT_DELETEKEYSET);
2657     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2658     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2659      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2660     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2661      CRYPT_VERIFYCONTEXT);
2662     ok(!result && GetLastError() == NTE_BAD_FLAGS,
2663      "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2664     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2665      CRYPT_NEWKEYSET);
2666     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2667     if (!result) return;
2668     /* Test provider parameters getter */
2669     dataLen = sizeof(dwParam);
2670     result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2671     ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2672         "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2673     dataLen = sizeof(dwParam);
2674     result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2675     ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2676         "Expected 0, got 0x%08X\n",dwParam);
2677     dataLen = sizeof(dwParam);
2678     result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2679     ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2680         "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2681     dataLen = sizeof(keySpec);
2682     SetLastError(0xdeadbeef);
2683     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2684     if (!result && GetLastError() == NTE_BAD_TYPE)
2685         skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2686     else
2687         ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2688             "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2689     /* PP_CONTAINER parameter */
2690     dataLen = sizeof(szName);
2691     result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2692     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2693         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2694         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2695     /* PP_UNIQUE_CONTAINER parameter */
2696     dataLen = sizeof(szName);
2697     SetLastError(0xdeadbeef);
2698     result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2699     if (!result && GetLastError() == NTE_BAD_TYPE)
2700     {
2701         skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2702     }
2703     else
2704     {
2705         char container[MAX_PATH];
2706
2707         ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2708         uniquecontainer(container);
2709         todo_wine
2710         {
2711             ok(dataLen == strlen(container)+1 ||
2712                broken(dataLen == strlen(szContainer)+1) /* WinME */,
2713                "Expected a param length of 70, got %d\n", dataLen);
2714             ok(!strcmp(container, szName) ||
2715                broken(!strcmp(szName, szContainer)) /* WinME */,
2716                "Wrong container name : %s\n", szName);
2717         }
2718     }
2719     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2720     ok(!result && GetLastError() == NTE_NO_KEY,
2721      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2722     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2723     ok(!result && GetLastError() == NTE_NO_KEY,
2724      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2725
2726     /* Importing a key exchange blob.. */
2727     result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2728      0, 0, &key);
2729     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2730     CryptDestroyKey(key);
2731     /* allows access to the key exchange key.. */
2732     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2733     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2734     CryptDestroyKey(key);
2735     /* but not to the private key. */
2736     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2737     ok(!result && GetLastError() == NTE_NO_KEY,
2738      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2739     CryptReleaseContext(prov, 0);
2740     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2741      CRYPT_DELETEKEYSET);
2742
2743     /* Whereas importing a sign blob.. */
2744     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2745      CRYPT_NEWKEYSET);
2746     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2747     if (!result) return;
2748     result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2749     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2750     CryptDestroyKey(key);
2751     /* doesn't allow access to the key exchange key.. */
2752     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2753     ok(!result && GetLastError() == NTE_NO_KEY,
2754      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2755     /* but does to the private key. */
2756     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2757     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2758     CryptDestroyKey(key);
2759     CryptReleaseContext(prov, 0);
2760
2761     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2762      CRYPT_DELETEKEYSET);
2763
2764     /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2765     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2766      CRYPT_NEWKEYSET);
2767     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2768     result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2769     ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2770     CryptDestroyKey(key);
2771     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2772     ok(!result, "expected CryptGetUserKey to fail\n");
2773     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2774     ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2775     CryptDestroyKey(key);
2776     CryptReleaseContext(prov, 0);
2777
2778     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2779      CRYPT_DELETEKEYSET);
2780
2781     /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2782     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2783      CRYPT_NEWKEYSET);
2784     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2785     result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2786     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2787     CryptDestroyKey(key);
2788     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2789     ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2790     CryptDestroyKey(key);
2791     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2792     ok(!result, "expected CryptGetUserKey to fail\n");
2793     CryptReleaseContext(prov, 0);
2794
2795     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2796      CRYPT_DELETEKEYSET);
2797
2798     /* test for the bug in accessing the user key in a container
2799      */
2800     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2801      CRYPT_NEWKEYSET);
2802     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2803     result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2804     ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2805     CryptDestroyKey(key);
2806     CryptReleaseContext(prov,0);
2807     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2808     ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2809     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2810     ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2811     CryptDestroyKey(key);
2812     CryptReleaseContext(prov, 0);
2813
2814     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2815      CRYPT_DELETEKEYSET);
2816
2817     /* test the machine key set */
2818     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2819      CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2820     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2821      CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2822     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2823     CryptReleaseContext(prov, 0);
2824     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2825      CRYPT_MACHINE_KEYSET);
2826     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2827     CryptReleaseContext(prov,0);
2828     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2829        CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2830     ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2831                 GetLastError());
2832     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2833      CRYPT_MACHINE_KEYSET);
2834     ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2835         "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2836
2837 }
2838
2839 static void test_key_permissions(void)
2840 {
2841     HCRYPTKEY hKey1, hKey2;
2842     DWORD dwVal, dwLen;
2843     BOOL result;
2844
2845     /* Create keys that are exportable */
2846     if (!init_base_environment(CRYPT_EXPORTABLE))
2847         return;
2848
2849     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2850     ok (result, "%08x\n", GetLastError());
2851     if (!result) return;
2852
2853     dwVal = 0xdeadbeef;
2854     dwLen = sizeof(DWORD);
2855     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2856     ok(result, "%08x\n", GetLastError());
2857     ok(dwVal ==
2858         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2859         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2860         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2861         " got %08x\n", dwVal);
2862
2863     /* The key exchange key's public key may be exported.. */
2864     result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2865     ok(result, "%08x\n", GetLastError());
2866     /* and its private key may be too. */
2867     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2868     ok(result, "%08x\n", GetLastError());
2869     /* Turning off the key's export permissions is "allowed".. */
2870     dwVal &= ~CRYPT_EXPORT;
2871     result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2872     ok(result ||
2873         broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2874         broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2875         "%08x\n", GetLastError());
2876     /* but it has no effect. */
2877     dwVal = 0xdeadbeef;
2878     dwLen = sizeof(DWORD);
2879     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2880     ok(result, "%08x\n", GetLastError());
2881     ok(dwVal ==
2882         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2883         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2884         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2885         " got %08x\n", dwVal);
2886     /* Thus, changing the export flag of the key doesn't affect whether the key
2887      * may be exported.
2888      */
2889     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2890     ok(result, "%08x\n", GetLastError());
2891
2892     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2893     ok (result, "%08x\n", GetLastError());
2894
2895     /* A subsequent get of the same key, into a different handle, also doesn't
2896      * show that the permissions have been changed.
2897      */
2898     dwVal = 0xdeadbeef;
2899     dwLen = sizeof(DWORD);
2900     result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2901     ok(result, "%08x\n", GetLastError());
2902     ok(dwVal ==
2903         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2904         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2905         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2906         " got %08x\n", dwVal);
2907
2908     CryptDestroyKey(hKey2);
2909     CryptDestroyKey(hKey1);
2910
2911     clean_up_base_environment();
2912 }
2913
2914 static void test_key_initialization(void)
2915 {
2916     DWORD dwLen;
2917     HCRYPTPROV prov1, prov2;
2918     HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2919     BOOL result;
2920     static BYTE abSessionKey[148] = {
2921         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2922         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2923         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2924         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2925         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2926         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2927         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2928         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2929         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2930         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2931         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2932         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2933         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2934         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2935         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2936         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2937         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2938         0x04, 0x8c, 0x49, 0x92
2939     };
2940
2941     /* Like init_base_environment, but doesn't generate new keys, as they'll
2942      * be imported instead.
2943      */
2944     if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2945     {
2946         result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2947                                      CRYPT_NEWKEYSET);
2948         ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2949     }
2950     dwLen = (DWORD)sizeof(abPlainPrivateKey);
2951     result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2952     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2953
2954     dwLen = (DWORD)sizeof(abSessionKey);
2955     result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2956     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2957
2958     /* Once the key has been imported, subsequently acquiring a context with
2959      * the same name will allow retrieving the key.
2960      */
2961     result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2962     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2963     result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2964     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2965     if (result) CryptDestroyKey(hKey);
2966     CryptReleaseContext(prov2, 0);
2967
2968     CryptDestroyKey(hSessionKey);
2969     CryptDestroyKey(hKeyExchangeKey);
2970     CryptReleaseContext(prov1, 0);
2971     CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2972      CRYPT_DELETEKEYSET);
2973 }
2974
2975 START_TEST(rsaenh)
2976 {
2977     if (!init_base_environment(0))
2978         return;
2979     test_prov();
2980     test_gen_random();
2981     test_hashes();
2982     test_rc4();
2983     test_rc2();
2984     test_des();
2985     test_3des112();
2986     test_3des();
2987     test_hmac();
2988     test_mac();
2989     test_block_cipher_modes();
2990     test_import_private();
2991     test_verify_signature();
2992     test_rsa_encrypt();
2993     test_import_export();
2994     test_import_hmac();
2995     test_enum_container();
2996     clean_up_base_environment();
2997     test_key_permissions();
2998     test_key_initialization();
2999     test_schannel_provider();
3000     test_null_provider();
3001     test_rsa_round_trip();
3002     if (!init_aes_environment())
3003         return;
3004     test_aes(128);
3005     test_aes(192);
3006     test_aes(256);
3007     test_sha2();
3008     clean_up_aes_environment();
3009 }