urlmon: Added stub for CoInternetGetSecurityUrlEx.
[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
1252         dwLen = sizeof(dwKeyLen);
1253         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1254         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1255         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1256         ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1257
1258         dwKeyLen = 128;
1259         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1260         ok(result, "%d\n", GetLastError());
1261
1262         dwLen = sizeof(dwKeyLen);
1263         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1264         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1265         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1266         ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1267
1268         result = CryptDestroyHash(hHash);
1269         ok(result, "%08x\n", GetLastError());
1270
1271         dwDataLen = 13;
1272         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1273         ok(result, "%08x\n", GetLastError());
1274
1275         ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1276                 "RC2 encryption failed!\n");
1277
1278         /* Oddly enough this succeeds, though it should have no effect */
1279         dwKeyLen = 40;
1280         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1281         ok(result, "%d\n", GetLastError());
1282
1283         result = CryptDestroyKey(hKey);
1284         ok(result, "%08x\n", GetLastError());
1285     }
1286 }
1287
1288 static void test_rc4(void)
1289 {
1290     static const BYTE rc4[16] = { 
1291         0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0, 
1292         0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };    
1293     BOOL result;
1294     HCRYPTHASH hHash;
1295     HCRYPTKEY hKey;
1296     DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1297     unsigned char pbData[2000], *pbTemp;
1298     unsigned char pszBuffer[256];
1299     int i;
1300
1301     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1302
1303     /* MD2 Hashing */
1304     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1305     if (!result) {
1306         /* rsaenh compiled without OpenSSL */
1307         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1308     } else {
1309         CRYPT_INTEGER_BLOB salt;
1310
1311         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1312            ok(result, "%08x\n", GetLastError());
1313
1314         dwLen = 16;
1315         result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1316         ok(result, "%08x\n", GetLastError());
1317
1318         result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1319         ok(result, "%08x\n", GetLastError());
1320
1321         dwLen = sizeof(DWORD);
1322         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1323         ok(result, "%08x\n", GetLastError());
1324
1325         dwLen = sizeof(DWORD);
1326         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1327         ok(result, "%08x\n", GetLastError());
1328
1329         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1330         ok(result, "%08x\n", GetLastError());
1331         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1332         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1333         HeapFree(GetProcessHeap(), 0, pbTemp);
1334
1335         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1336         ok(result, "%08x\n", GetLastError());
1337         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1338         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1339         HeapFree(GetProcessHeap(), 0, pbTemp);
1340
1341         dwLen = sizeof(DWORD);
1342         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1343
1344         result = CryptDestroyHash(hHash);
1345         ok(result, "%08x\n", GetLastError());
1346
1347         dwDataLen = 16;
1348         result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1349         ok(result, "%08x\n", GetLastError());
1350         dwDataLen = 16;
1351         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1352         ok(result, "%08x\n", GetLastError());
1353
1354         ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1355
1356         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1357         ok(result, "%08x\n", GetLastError());
1358
1359         /* Setting the salt also succeeds... */
1360         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1361         ok(result, "setting salt failed: %08x\n", GetLastError());
1362         /* but the resulting salt length is now zero? */
1363         dwLen = 0;
1364         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1365         ok(result, "%08x\n", GetLastError());
1366         ok(dwLen == 0 ||
1367            broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1368            "unexpected salt length %d\n", dwLen);
1369         /* What sizes salt can I set? */
1370         salt.pbData = pbData;
1371         for (i=0; i<24; i++)
1372         {
1373             salt.cbData = i;
1374             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1375             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1376             /* The returned salt length is the same as the set salt length */
1377             result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1378             ok(result, "%08x\n", GetLastError());
1379             ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1380         }
1381         salt.cbData = 25;
1382         SetLastError(0xdeadbeef);
1383         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1384         ok(!result ||
1385            broken(result), /* Win9x, WinMe, NT4, W2K */
1386            "%08x\n", GetLastError());
1387
1388         result = CryptDestroyKey(hKey);
1389         ok(result, "%08x\n", GetLastError());
1390     }
1391 }
1392
1393 static void test_hmac(void) {
1394     HCRYPTKEY hKey;
1395     HCRYPTHASH hHash;
1396     BOOL result;
1397     /* Using CALG_MD2 here fails on Windows 2003, why ? */
1398     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1399     DWORD dwLen;
1400     BYTE abData[256];
1401     static const BYTE hmac[16] = { 
1402         0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c, 
1403         0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1404     int i;
1405
1406     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1407
1408     if (!derive_key(CALG_RC2, &hKey, 56)) return;
1409
1410     result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1411     ok(result, "%08x\n", GetLastError());
1412     if (!result) return;
1413
1414     result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1415     ok(result, "%08x\n", GetLastError());
1416
1417     result = CryptHashData(hHash, abData, sizeof(abData), 0);
1418     ok(result, "%08x\n", GetLastError());
1419
1420     dwLen = sizeof(abData)/sizeof(BYTE);
1421     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1422     ok(result, "%08x\n", GetLastError());
1423
1424     ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1425     
1426     result = CryptDestroyHash(hHash);
1427     ok(result, "%08x\n", GetLastError());
1428     
1429     result = CryptDestroyKey(hKey);
1430     ok(result, "%08x\n", GetLastError());
1431
1432     /* Provoke errors */
1433     result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1434     ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1435 }
1436
1437 static void test_mac(void) {
1438     HCRYPTKEY hKey;
1439     HCRYPTHASH hHash;
1440     BOOL result;
1441     DWORD dwLen;
1442     BYTE abData[256], abEnc[264];
1443     static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1444     int i;
1445
1446     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1447     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1448
1449     if (!derive_key(CALG_RC2, &hKey, 40)) return;
1450
1451     dwLen = 256;
1452     result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1453     ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1454     
1455     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1456     ok(result, "%08x\n", GetLastError());
1457     if (!result) return;
1458
1459     result = CryptHashData(hHash, abData, sizeof(abData), 0);
1460     ok(result, "%08x\n", GetLastError());
1461
1462     dwLen = sizeof(abData)/sizeof(BYTE);
1463     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1464     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1465
1466     ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1467     
1468     result = CryptDestroyHash(hHash);
1469     ok(result, "%08x\n", GetLastError());
1470     
1471     result = CryptDestroyKey(hKey);
1472     ok(result, "%08x\n", GetLastError());
1473     
1474     /* Provoke errors */
1475     if (!derive_key(CALG_RC4, &hKey, 56)) return;
1476
1477     SetLastError(0xdeadbeef);
1478     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1479     ok((!result && GetLastError() == NTE_BAD_KEY) ||
1480             broken(result), /* Win9x, WinMe, NT4, W2K */
1481             "%08x\n", GetLastError());
1482
1483     result = CryptDestroyKey(hKey);
1484     ok(result, "%08x\n", GetLastError());
1485 }
1486
1487 static void test_import_private(void) 
1488 {
1489     DWORD dwLen, dwVal;
1490     HCRYPTKEY hKeyExchangeKey, hSessionKey;
1491     BOOL result;
1492     static BYTE abSessionKey[148] = {
1493         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1494         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1495         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1496         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1497         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1498         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1499         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1500         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1501         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1502         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1503         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1504         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1505         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1506         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1507         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1508         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1509         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1510         0x04, 0x8c, 0x49, 0x92
1511     };
1512     static BYTE abEncryptedMessage[12] = {
1513         0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1514         0x1c, 0xfd, 0xde, 0x71
1515     };
1516             
1517     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1518     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1519     if (!result) {
1520         /* rsaenh compiled without OpenSSL */
1521         ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1522         return;
1523     }
1524
1525     dwLen = (DWORD)sizeof(abSessionKey);
1526     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1527     ok(result, "%08x\n", GetLastError());
1528     if (!result) return;
1529
1530     dwVal = 0xdeadbeef;
1531     dwLen = sizeof(DWORD);
1532     result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1533     ok(result, "%08x\n", GetLastError());
1534     ok(dwVal ==
1535         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1536         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1537         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1538         " got %08x\n", dwVal);
1539
1540     dwLen = (DWORD)sizeof(abEncryptedMessage);
1541     result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1542     ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12), 
1543        "%08x, len: %d\n", GetLastError(), dwLen);
1544     CryptDestroyKey(hSessionKey);
1545     
1546     if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1547
1548     dwLen = (DWORD)sizeof(abSessionKey);
1549     result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1550     ok(result, "%08x\n", GetLastError());
1551     CryptDestroyKey(hSessionKey);
1552     if (!result) return;
1553
1554     dwLen = (DWORD)sizeof(abSessionKey);
1555     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1556     ok(result, "%08x\n", GetLastError());
1557     if (!result) return;
1558
1559     CryptDestroyKey(hSessionKey);
1560     CryptDestroyKey(hKeyExchangeKey);
1561 }
1562
1563 static void test_verify_signature(void) {
1564     HCRYPTHASH hHash;
1565     HCRYPTKEY hPubSignKey;
1566     BYTE abData[] = "Wine rocks!";
1567     BOOL result;
1568     BYTE abPubKey[148] = {
1569         0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 
1570         0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 
1571         0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19, 
1572         0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27, 
1573         0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8, 
1574         0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda, 
1575         0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a, 
1576         0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc, 
1577         0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c, 
1578         0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c, 
1579         0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89, 
1580         0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b, 
1581         0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa, 
1582         0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63, 
1583         0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff, 
1584         0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49, 
1585         0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87, 
1586         0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7, 
1587         0xe1, 0x21, 0x50, 0xac
1588     };
1589     /* md2 with hash oid */
1590     BYTE abSignatureMD2[128] = {
1591         0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67, 
1592         0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b, 
1593         0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda, 
1594         0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59, 
1595         0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a, 
1596         0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34, 
1597         0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40, 
1598         0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7, 
1599         0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0, 
1600         0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06, 
1601         0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51, 
1602         0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f, 
1603         0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46, 
1604         0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25, 
1605         0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0, 
1606         0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1607     };
1608     /* md2 without hash oid */
1609     BYTE abSignatureMD2NoOID[128] = {
1610         0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d, 
1611         0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19, 
1612         0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd, 
1613         0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4, 
1614         0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65, 
1615         0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99, 
1616         0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf, 
1617         0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc, 
1618         0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0, 
1619         0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01, 
1620         0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7, 
1621         0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f, 
1622         0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a, 
1623         0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9, 
1624         0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06, 
1625         0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1626     };
1627     /* md4 with hash oid */
1628     BYTE abSignatureMD4[128] = {
1629         0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51, 
1630         0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b, 
1631         0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2, 
1632         0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e, 
1633         0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13, 
1634         0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9, 
1635         0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f, 
1636         0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96, 
1637         0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9, 
1638         0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e, 
1639         0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0, 
1640         0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe, 
1641         0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18, 
1642         0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab, 
1643         0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3, 
1644         0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1645     };
1646     /* md4 without hash oid */
1647     BYTE abSignatureMD4NoOID[128] = {
1648         0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda, 
1649         0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24, 
1650         0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0, 
1651         0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36, 
1652         0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85, 
1653         0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3, 
1654         0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f, 
1655         0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9, 
1656         0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06, 
1657         0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f, 
1658         0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb, 
1659         0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96, 
1660         0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f, 
1661         0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9, 
1662         0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb, 
1663         0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1664     }; 
1665     /* md5 with hash oid */
1666     BYTE abSignatureMD5[128] = {
1667         0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5, 
1668         0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f, 
1669         0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7, 
1670         0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98, 
1671         0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec, 
1672         0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5, 
1673         0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04, 
1674         0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b, 
1675         0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95, 
1676         0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c, 
1677         0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29, 
1678         0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9, 
1679         0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c, 
1680         0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90, 
1681         0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e, 
1682         0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1683     };
1684     /* md5 without hash oid */
1685     BYTE abSignatureMD5NoOID[128] = {
1686         0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f, 
1687         0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75, 
1688         0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f, 
1689         0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d, 
1690         0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f, 
1691         0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49, 
1692         0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8, 
1693         0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c, 
1694         0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23, 
1695         0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19, 
1696         0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb, 
1697         0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3, 
1698         0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b, 
1699         0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b, 
1700         0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5, 
1701         0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1702     };
1703     /* sha with hash oid */
1704     BYTE abSignatureSHA[128] = {
1705         0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91, 
1706         0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd, 
1707         0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24, 
1708         0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94, 
1709         0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f, 
1710         0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a, 
1711         0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52, 
1712         0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20, 
1713         0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5, 
1714         0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a, 
1715         0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff, 
1716         0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53, 
1717         0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00, 
1718         0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e, 
1719         0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98, 
1720         0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1721     };
1722     /* sha without hash oid */
1723     BYTE abSignatureSHANoOID[128] = {
1724         0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6, 
1725         0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a, 
1726         0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f, 
1727         0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37, 
1728         0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65, 
1729         0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe, 
1730         0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6, 
1731         0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe, 
1732         0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c, 
1733         0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4, 
1734         0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80, 
1735         0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a, 
1736         0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00, 
1737         0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd, 
1738         0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67, 
1739         0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1740     }; 
1741     
1742     result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1743     ok(result, "%08x\n", GetLastError());
1744     if (!result) return;
1745
1746     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1747     ok(result, "%08x\n", GetLastError());
1748     if (!result) return;
1749
1750     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1751     ok(result, "%08x\n", GetLastError());
1752     if (!result) return;
1753
1754     /*check that a NULL pointer signature is correctly handled*/
1755     result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1756     ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1757      "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1758     if (result) return;
1759
1760     /* check that we get a bad signature error when the signature is too short*/
1761     SetLastError(0xdeadbeef);
1762     result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1763     ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1764      broken(result), /* Win9x, WinMe, NT4 */
1765      "Expected NTE_BAD_SIGNATURE, got %08x\n",  GetLastError());
1766
1767     result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1768     ok(result, "%08x\n", GetLastError());
1769     if (!result) return;
1770
1771     result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1772     ok(result, "%08x\n", GetLastError());
1773     if (!result) return;
1774
1775     /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about 
1776      * the OID at all. */
1777     /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1778     ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1779     if (result) return;*/
1780
1781     CryptDestroyHash(hHash);
1782
1783     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1784     ok(result, "%08x\n", GetLastError());
1785     if (!result) return;
1786
1787     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1788     ok(result, "%08x\n", GetLastError());
1789     if (!result) return;
1790
1791     result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1792     ok(result, "%08x\n", GetLastError());
1793     if (!result) return;
1794
1795     result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1796     ok(result, "%08x\n", GetLastError());
1797     if (!result) return;
1798
1799     CryptDestroyHash(hHash);
1800
1801     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1802     ok(result, "%08x\n", GetLastError());
1803     if (!result) return;
1804
1805     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1806     ok(result, "%08x\n", GetLastError());
1807     if (!result) return;
1808
1809     result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1810     ok(result, "%08x\n", GetLastError());
1811     if (!result) return;
1812
1813     result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1814     ok(result, "%08x\n", GetLastError());
1815     if (!result) return;
1816
1817     CryptDestroyHash(hHash);
1818
1819     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1820     ok(result, "%08x\n", GetLastError());
1821     if (!result) return;
1822
1823     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1824     ok(result, "%08x\n", GetLastError());
1825     if (!result) return;
1826
1827     result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1828     ok(result, "%08x\n", GetLastError());
1829     if (!result) return;
1830
1831     result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1832     ok(result, "%08x\n", GetLastError());
1833     if (!result) return;
1834
1835     CryptDestroyHash(hHash);
1836     CryptDestroyKey(hPubSignKey);
1837 }
1838
1839 static void test_rsa_encrypt(void)
1840 {
1841     HCRYPTKEY hRSAKey;
1842     BYTE abData[2048] = "Wine rocks!";
1843     BOOL result;
1844     DWORD dwVal, dwLen;
1845
1846     /* It is allowed to use the key exchange key for encryption/decryption */
1847     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1848     ok (result, "%08x\n", GetLastError());
1849     if (!result) return;
1850
1851     dwLen = 12;
1852     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1853     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1854     ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1855     dwLen = 12;
1856     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1857     ok (result, "%08x\n", GetLastError());
1858     if (!result) return;
1859
1860     result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1861     ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1862     
1863     dwVal = 0xdeadbeef;
1864     dwLen = sizeof(DWORD);
1865     result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1866     ok(result, "%08x\n", GetLastError());
1867     ok(dwVal ==
1868         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1869         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1870         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1871         " got %08x\n", dwVal);
1872
1873     /* An RSA key doesn't support salt */
1874     result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1875     ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
1876        "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
1877
1878     /* The key exchange key's public key may be exported.. */
1879     result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1880     ok(result, "%08x\n", GetLastError());
1881     /* but its private key may not be. */
1882     SetLastError(0xdeadbeef);
1883     result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1884     ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1885         broken(result), /* Win9x/NT4 */
1886         "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1887     /* Setting the permissions of the key exchange key isn't allowed, either. */
1888     dwVal |= CRYPT_EXPORT;
1889     SetLastError(0xdeadbeef);
1890     result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1891     ok(!result &&
1892         (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1893         "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1894
1895     CryptDestroyKey(hRSAKey);
1896
1897     /* It is not allowed to use the signature key for encryption/decryption */
1898     result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1899     ok (result, "%08x\n", GetLastError());
1900     if (!result) return;
1901
1902     dwVal = 0xdeadbeef;
1903     dwLen = sizeof(DWORD);
1904     result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1905     ok(result, "%08x\n", GetLastError());
1906     ok(dwVal ==
1907         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1908         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1909         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1910         " got %08x\n", dwVal);
1911
1912     /* The signature key's public key may also be exported.. */
1913     result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1914     ok(result, "%08x\n", GetLastError());
1915     /* but its private key may not be. */
1916     SetLastError(0xdeadbeef);
1917     result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1918     ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1919         broken(result), /* Win9x/NT4 */
1920         "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1921     /* Setting the permissions of the signature key isn't allowed, either. */
1922     dwVal |= CRYPT_EXPORT;
1923     SetLastError(0xdeadbeef);
1924     result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1925     ok(!result &&
1926         (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1927         "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1928
1929     dwLen = 12;
1930     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1931     ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1932
1933     CryptDestroyKey(hRSAKey);
1934 }
1935
1936 static void test_import_export(void)
1937 {
1938     DWORD dwLen, dwDataLen, dwVal;
1939     HCRYPTKEY hPublicKey, hPrivKey;
1940     BOOL result;
1941     ALG_ID algID;
1942     BYTE emptyKey[2048], *exported_key;
1943     static BYTE abPlainPublicKey[84] = {
1944         0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1945         0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1946         0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1947         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1948         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1949         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1950         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1951         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1952         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1953         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1954         0x11, 0x11, 0x11, 0x11
1955     };
1956     static BYTE priv_key_with_high_bit[] = {
1957         0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1958         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1959         0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1960         0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1961         0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1962         0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1963         0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1964         0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1965         0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1966         0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1967         0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1968         0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1969         0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1970         0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1971         0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1972         0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1973         0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1974         0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1975         0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1976         0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1977         0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1978         0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1979         0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1980         0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1981         0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1982         0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1983         0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1984         0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1985         0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1986         0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1987         0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1988         0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1989         0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1990         0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1991         0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1992         0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1993         0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1994         0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1995         0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1996         0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1997         0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1998         0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1999         0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2000         0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2001         0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2002         0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2003         0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2004         0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2005         0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2006         0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2007         0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2008         0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2009         0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2010         0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2011         0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2012         0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2013         0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2014         0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2015         0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2016         0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2017         0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2018         0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2019         0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2020         0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2021         0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2022         0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2023         0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2024         0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2025         0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2026         0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2027         0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2028         0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2029         0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2030         0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2031         0xb6, 0x5f, 0x01, 0x5e
2032     };
2033     static const BYTE expected_exported_priv_key[] = {
2034         0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2035         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2036         0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2037         0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2038         0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2039         0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2040         0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2041         0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2042         0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2043         0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2044         0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2045         0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2046         0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2047         0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2048         0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2049         0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2050         0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2051         0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2052         0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2053         0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2054         0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2055         0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2056         0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2057         0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2058         0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2059         0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2060         0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2061         0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2062         0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2063         0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2064         0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2065         0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2066         0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2067         0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2068         0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2069         0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2070         0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2071         0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2072         0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2073         0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2074         0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2075         0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2076         0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2077         0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2078         0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2079         0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2080         0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2081         0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2082         0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2083         0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2084         0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2085         0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2086         0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2087         0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2088         0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2089         0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2090         0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2091         0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2092         0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2093         0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2094         0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2095         0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2096         0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2097         0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2098         0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2099         0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2100         0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2101         0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2102         0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2103         0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2104         0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2105         0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2106         0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2107         0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2108         0xb6, 0x5f, 0x01, 0x5e
2109     };
2110
2111     dwLen=84;
2112     result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2113     ok(result, "failed to import the public key\n");
2114
2115     dwDataLen=sizeof(algID);
2116     result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2117     ok(result, "failed to get the KP_ALGID from the imported public key\n");
2118     ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2119         
2120     dwVal = 0xdeadbeef;
2121     dwDataLen = sizeof(DWORD);
2122     result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2123     ok(result, "%08x\n", GetLastError());
2124     ok(dwVal ==
2125         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2126         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2127         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2128         " got %08x\n", dwVal);
2129     result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2130     ok(result, "failed to export the fresh imported public key\n");
2131     ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2132     ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2133
2134     CryptDestroyKey(hPublicKey);
2135
2136     result = CryptImportKey(hProv, priv_key_with_high_bit,
2137         sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2138     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2139
2140     result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2141     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2142     exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2143     result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2144         &dwDataLen);
2145     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2146
2147     ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2148         dwDataLen);
2149     ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2150         "unexpected value\n");
2151
2152     HeapFree(GetProcessHeap(), 0, exported_key);
2153
2154     CryptDestroyKey(hPrivKey);
2155 }
2156
2157 static void test_import_hmac(void)
2158 {
2159     /* Test cases from RFC 2202, section 3 */
2160     static const struct rfc2202_test_case {
2161         const char *key;
2162         DWORD key_len;
2163         const char *data;
2164         const DWORD data_len;
2165         const char *digest;
2166     } cases[] = {
2167         { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2168           "\x0b\x0b\x0b\x0b", 20,
2169           "Hi There", 8,
2170           "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2171           "\xf1\x46\xbe\x00" },
2172         { "Jefe", 4,
2173           "what do ya want for nothing?", 28,
2174           "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2175           "\x25\x9a\x7c\x79" },
2176         { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2177           "\xaa\xaa\xaa\xaa", 20,
2178           "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
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", 50,
2182           "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2183           "\x63\xf1\x75\xd3" },
2184         { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2185           "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2186           "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
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", 50,
2190           "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2191           "\x2d\x72\x35\xda" },
2192         { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2193           "\x0c\x0c\x0c\x0c", 20,
2194           "Test With Truncation", 20,
2195           "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2196           "\x4a\x9a\x5a\x04" },
2197         { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
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           80,
2203           "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2204           "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2205           "\xed\x40\x21\x12" },
2206         { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
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           80,
2212           "Test Using Larger Than Block-Size Key and Larger "
2213           "Than One Block-Size Data", 73,
2214           "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2215           "\xbb\xff\x1a\x91" }
2216     };
2217     DWORD i;
2218
2219     for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++)
2220     {
2221         const struct rfc2202_test_case *test_case = &cases[i];
2222         DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2223         BYTE *blob = HeapAlloc(GetProcessHeap(), 0, size);
2224
2225         if (blob)
2226         {
2227             BLOBHEADER *header = (BLOBHEADER *)blob;
2228             DWORD *key_len = (DWORD *)(header + 1);
2229             BYTE *key_bytes = (BYTE *)(key_len + 1);
2230             BOOL result;
2231             HCRYPTKEY key;
2232
2233             header->bType = PLAINTEXTKEYBLOB;
2234             header->bVersion = CUR_BLOB_VERSION;
2235             header->reserved = 0;
2236             header->aiKeyAlg = CALG_RC2;
2237             *key_len = test_case->key_len;
2238             memcpy(key_bytes, test_case->key, *key_len);
2239             result = CryptImportKey(hProv, blob, size, 0, CRYPT_IPSEC_HMAC_KEY, &key);
2240             ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
2241             if (result)
2242             {
2243                 HCRYPTHASH hash;
2244                 HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2245                 BYTE digest[20];
2246                 DWORD digest_size;
2247
2248                 result = CryptCreateHash(hProv, CALG_HMAC, key, 0, &hash);
2249                 ok(result, "CryptCreateHash failed on test case %d: %08x\n", i, GetLastError());
2250                 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2251                 ok(result, "CryptSetHashParam failed on test case %d: %08x\n", i, GetLastError());
2252                 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2253                 ok(result, "CryptHashData failed on test case %d: %08x\n", i, GetLastError());
2254                 digest_size = sizeof(digest);
2255                 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2256                 ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
2257                 ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected value on test case %d\n", i);
2258                 CryptDestroyHash(hash);
2259                 CryptDestroyKey(key);
2260             }
2261             HeapFree(GetProcessHeap(), 0, blob);
2262         }
2263     }
2264 }
2265         
2266 static void test_schannel_provider(void)
2267 {
2268     HCRYPTPROV hProv;
2269     HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2270     HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2271     BOOL result;
2272     DWORD dwLen;
2273     SCHANNEL_ALG saSChannelAlg;
2274     CRYPT_DATA_BLOB data_blob;
2275     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2276     BYTE abTLS1Master[140] = {
2277         0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00, 
2278         0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68, 
2279         0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97, 
2280         0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53, 
2281         0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24, 
2282         0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3, 
2283         0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8, 
2284         0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d, 
2285         0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e, 
2286         0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e, 
2287         0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40, 
2288         0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b, 
2289         0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb, 
2290         0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6, 
2291         0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac, 
2292         0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41, 
2293         0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4, 
2294         0xd3, 0x1e, 0x82, 0xb3
2295     };
2296     BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2297     BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2298     BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2299     BYTE abClientFinished[16] = "client finished";
2300     BYTE abData[16] = "Wine rocks!";
2301     BYTE abMD5Hash[16];
2302     static const BYTE abEncryptedData[16] = {
2303         0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2304         0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d    
2305     };
2306     static const BYTE abPRF[16] = {
2307         0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2308         0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2309     };
2310     static const BYTE abMD5[16] = {
2311         0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2312         0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2313     };
2314     
2315     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2316     if (!result)
2317     {
2318         win_skip("no PROV_RSA_SCHANNEL support\n");
2319         return;
2320     }
2321     ok (result, "%08x\n", GetLastError());
2322     if (result)
2323         CryptReleaseContext(hProv, 0);
2324
2325     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2326     ok (result, "%08x\n", GetLastError());
2327     if (!result) return;
2328     
2329     /* To get deterministic results, we import the TLS1 master secret (which
2330      * is typically generated from a random generator). Therefore, we need
2331      * an RSA key. */
2332     dwLen = (DWORD)sizeof(abPlainPrivateKey);
2333     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2334     ok (result, "%08x\n", GetLastError());
2335     if (!result) return;
2336
2337     dwLen = (DWORD)sizeof(abTLS1Master);
2338     result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2339     ok (result, "%08x\n", GetLastError());
2340     if (!result) return;    
2341    
2342     /* Setting the TLS1 client and server random parameters, as well as the 
2343      * MAC and encryption algorithm parameters. */
2344     data_blob.cbData = 33;
2345     data_blob.pbData = abClientSecret;
2346     result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2347     ok (result, "%08x\n", GetLastError());
2348     if (!result) return;
2349
2350     data_blob.cbData = 33;
2351     data_blob.pbData = abServerSecret;
2352     result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2353     ok (result, "%08x\n", GetLastError());
2354     if (!result) return;
2355     
2356     saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2357     saSChannelAlg.Algid = CALG_DES;
2358     saSChannelAlg.cBits = 64;
2359     saSChannelAlg.dwFlags = 0;
2360     saSChannelAlg.dwReserved = 0;
2361     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2362     ok (result, "%08x\n", GetLastError());
2363     if (!result) return;
2364
2365     saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2366     saSChannelAlg.Algid = CALG_MD5;
2367     saSChannelAlg.cBits = 128;
2368     saSChannelAlg.dwFlags = 0;
2369     saSChannelAlg.dwReserved = 0;
2370     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2371     ok (result, "%08x\n", GetLastError());
2372     if (!result) return;
2373
2374     /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2375      * (Keys can only be derived from hashes, not from other keys.) */
2376     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2377     ok (result, "%08x\n", GetLastError());
2378     if (!result) return;
2379
2380     /* Deriving the server write encryption key from the master hash */
2381     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2382     ok (result, "%08x\n", GetLastError());
2383     if (!result) return;
2384
2385     /* Encrypting some data with the server write encryption key and checking the result. */
2386     dwLen = 12;
2387     result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2388     ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2389
2390     /* Second test case: Test the TLS1 pseudo random number function. */
2391     result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2392     ok (result, "%08x\n", GetLastError());
2393     if (!result) return;
2394
2395     /* Set the label and seed parameters for the random number function */
2396     data_blob.cbData = 36;
2397     data_blob.pbData = abHashedHandshakes;
2398     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2399     ok (result, "%08x\n", GetLastError());
2400     if (!result) return;
2401
2402     data_blob.cbData = 15;
2403     data_blob.pbData = abClientFinished;
2404     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2405     ok (result, "%08x\n", GetLastError());
2406     if (!result) return;
2407
2408     /* Generate some pseudo random bytes and check if they are correct. */
2409     dwLen = (DWORD)sizeof(abData);
2410     result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2411     ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)), 
2412         "%08x\n", GetLastError());
2413
2414     /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2415      * Hash some data with the HMAC. Compare results. */
2416     result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2417     ok (result, "%08x\n", GetLastError());
2418     if (!result) return;
2419     
2420     result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2421     ok (result, "%08x\n", GetLastError());
2422     if (!result) return;
2423
2424     result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2425     ok (result, "%08x\n", GetLastError());
2426     if (!result) return;
2427
2428     result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2429     ok (result, "%08x\n", GetLastError());
2430     if (!result) return;
2431
2432     dwLen = (DWORD)sizeof(abMD5Hash);
2433     result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2434     ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2435
2436     CryptDestroyHash(hHMAC);
2437     CryptDestroyHash(hTLS1PRF);
2438     CryptDestroyHash(hMasterHash);
2439     CryptDestroyKey(hServerWriteMACKey);
2440     CryptDestroyKey(hServerWriteKey);
2441     CryptDestroyKey(hRSAKey);
2442     CryptDestroyKey(hMasterSecret);
2443     CryptReleaseContext(hProv, 0);
2444     CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2445 }
2446
2447 /* Test that a key can be used to encrypt data and exported, and that, when
2448  * the exported key is imported again, can be used to decrypt the original
2449  * data again.
2450  */
2451 static void test_rsa_round_trip(void)
2452 {
2453     static const char test_string[] = "Well this is a fine how-do-you-do.";
2454     HCRYPTPROV prov;
2455     HCRYPTKEY signKey, keyExchangeKey;
2456     BOOL result;
2457     BYTE data[256], *exportedKey;
2458     DWORD dataLen, keyLen;
2459
2460     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2461      CRYPT_DELETEKEYSET);
2462
2463     /* Generate a new key... */
2464     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2465      CRYPT_NEWKEYSET);
2466     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2467     result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2468     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2469     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2470     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2471     /* encrypt some data with it... */
2472     memcpy(data, test_string, strlen(test_string) + 1);
2473     dataLen = strlen(test_string) + 1;
2474     result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2475                           sizeof(data));
2476     ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2477        broken(GetLastError() == NTE_PERM /* NT4 */),
2478        "CryptEncrypt failed: %08x\n", GetLastError());
2479     /* export the key... */
2480     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2481                             &keyLen);
2482     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2483     exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2484     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2485                             &keyLen);
2486     /* destroy the key... */
2487     CryptDestroyKey(keyExchangeKey);
2488     CryptDestroyKey(signKey);
2489     /* import the key again... */
2490     result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2491     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2492     HeapFree(GetProcessHeap(), 0, exportedKey);
2493     /* and decrypt the data encrypted with the original key with the imported
2494      * key.
2495      */
2496     result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2497     ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2498        broken(GetLastError() == NTE_PERM /* NT4 */),
2499        "CryptDecrypt failed: %08x\n", GetLastError());
2500     if (result)
2501     {
2502         ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2503         ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2504     }
2505     CryptDestroyKey(keyExchangeKey);
2506     CryptReleaseContext(prov, 0);
2507
2508     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2509      CRYPT_DELETEKEYSET);
2510 }
2511
2512 static void test_enum_container(void)
2513 {
2514     BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2515     DWORD dwBufferLen;
2516     BOOL result, fFound = FALSE;
2517
2518     /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2519      * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2520     SetLastError(0xdeadbeef);
2521     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2522     ok (result, "%08x\n", GetLastError());
2523     ok (dwBufferLen == MAX_PATH + 1 ||
2524         broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2525         "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2526
2527     /* If the result fits into abContainerName dwBufferLen is left untouched */
2528     dwBufferLen = (DWORD)sizeof(abContainerName);
2529     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2530     ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2531     
2532     /* We only check, if the currently open 'winetest' container is among the enumerated. */
2533     do {
2534         if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2535         dwBufferLen = (DWORD)sizeof(abContainerName);
2536     } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2537         
2538     ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2539 }
2540
2541 static BYTE signBlob[] = {
2542 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2543 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2544 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2545 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2546 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2547 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2548 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2549 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2550 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2551 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2552 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2553 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2554 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2555 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2556 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2557 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2558 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2559 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2560 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2561 0xb6,0x85,0x86,0x07 };
2562
2563 static void test_null_provider(void)
2564 {
2565     HCRYPTPROV prov;
2566     HCRYPTKEY key;
2567     BOOL result;
2568     DWORD keySpec, dataLen,dwParam;
2569     char szName[MAX_PATH];
2570
2571     result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2572     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2573      "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2574     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2575     ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2576      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2577     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2578      CRYPT_DELETEKEYSET);
2579     ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2580      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2581     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2582      CRYPT_DELETEKEYSET);
2583     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2584      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2585     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2586     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2587      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2588
2589     /* Delete the default container. */
2590     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2591     /* Once you've deleted the default container you can't open it as if it
2592      * already exists.
2593      */
2594     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2595     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2596      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2597     /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2598     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2599      CRYPT_VERIFYCONTEXT);
2600     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2601     if (!result) return;
2602     dataLen = sizeof(keySpec);
2603     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2604     if (result)
2605         ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2606          "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2607     /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2608      * supported, you can't get the keys from this container.
2609      */
2610     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2611     ok(!result && GetLastError() == NTE_NO_KEY,
2612      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2613     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2614     ok(!result && GetLastError() == NTE_NO_KEY,
2615      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2616     result = CryptReleaseContext(prov, 0);
2617     ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2618     /* You can create a new default container. */
2619     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2620      CRYPT_NEWKEYSET);
2621     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2622     /* But you still can't get the keys (until one's been generated.) */
2623     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2624     ok(!result && GetLastError() == NTE_NO_KEY,
2625      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2626     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2627     ok(!result && GetLastError() == NTE_NO_KEY,
2628      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2629     CryptReleaseContext(prov, 0);
2630     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2631
2632     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2633      CRYPT_DELETEKEYSET);
2634     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2635     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2636      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2637     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2638      CRYPT_VERIFYCONTEXT);
2639     ok(!result && GetLastError() == NTE_BAD_FLAGS,
2640      "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2641     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2642      CRYPT_NEWKEYSET);
2643     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2644     if (!result) return;
2645     /* Test provider parameters getter */
2646     dataLen = sizeof(dwParam);
2647     result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2648     ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2649         "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2650     dataLen = sizeof(dwParam);
2651     result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2652     ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2653         "Expected 0, got 0x%08X\n",dwParam);
2654     dataLen = sizeof(dwParam);
2655     result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2656     ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2657         "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2658     dataLen = sizeof(keySpec);
2659     SetLastError(0xdeadbeef);
2660     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2661     if (!result && GetLastError() == NTE_BAD_TYPE)
2662         skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2663     else
2664         ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2665             "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2666     /* PP_CONTAINER parameter */
2667     dataLen = sizeof(szName);
2668     result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2669     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2670         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2671         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2672     /* PP_UNIQUE_CONTAINER parameter */
2673     dataLen = sizeof(szName);
2674     SetLastError(0xdeadbeef);
2675     result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2676     if (!result && GetLastError() == NTE_BAD_TYPE)
2677     {
2678         skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2679     }
2680     else
2681     {
2682         char container[MAX_PATH];
2683
2684         ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2685         uniquecontainer(container);
2686         todo_wine
2687         {
2688             ok(dataLen == strlen(container)+1 ||
2689                broken(dataLen == strlen(szContainer)+1) /* WinME */,
2690                "Expected a param length of 70, got %d\n", dataLen);
2691             ok(!strcmp(container, szName) ||
2692                broken(!strcmp(szName, szContainer)) /* WinME */,
2693                "Wrong container name : %s\n", szName);
2694         }
2695     }
2696     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2697     ok(!result && GetLastError() == NTE_NO_KEY,
2698      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2699     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2700     ok(!result && GetLastError() == NTE_NO_KEY,
2701      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2702
2703     /* Importing a key exchange blob.. */
2704     result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2705      0, 0, &key);
2706     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2707     CryptDestroyKey(key);
2708     /* allows access to the key exchange key.. */
2709     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2710     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2711     CryptDestroyKey(key);
2712     /* but not to the private key. */
2713     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2714     ok(!result && GetLastError() == NTE_NO_KEY,
2715      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2716     CryptReleaseContext(prov, 0);
2717     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2718      CRYPT_DELETEKEYSET);
2719
2720     /* Whereas importing a sign blob.. */
2721     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2722      CRYPT_NEWKEYSET);
2723     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2724     if (!result) return;
2725     result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2726     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2727     CryptDestroyKey(key);
2728     /* doesn't allow access to the key exchange key.. */
2729     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2730     ok(!result && GetLastError() == NTE_NO_KEY,
2731      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2732     /* but does to the private key. */
2733     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2734     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2735     CryptDestroyKey(key);
2736     CryptReleaseContext(prov, 0);
2737
2738     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2739      CRYPT_DELETEKEYSET);
2740
2741     /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2742     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2743      CRYPT_NEWKEYSET);
2744     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2745     result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2746     ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2747     CryptDestroyKey(key);
2748     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2749     ok(!result, "expected CryptGetUserKey to fail\n");
2750     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2751     ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2752     CryptDestroyKey(key);
2753     CryptReleaseContext(prov, 0);
2754
2755     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2756      CRYPT_DELETEKEYSET);
2757
2758     /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2759     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2760      CRYPT_NEWKEYSET);
2761     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2762     result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2763     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2764     CryptDestroyKey(key);
2765     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2766     ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2767     CryptDestroyKey(key);
2768     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2769     ok(!result, "expected CryptGetUserKey to fail\n");
2770     CryptReleaseContext(prov, 0);
2771
2772     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2773      CRYPT_DELETEKEYSET);
2774
2775     /* test for the bug in accessing the user key in a container
2776      */
2777     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2778      CRYPT_NEWKEYSET);
2779     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2780     result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2781     ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2782     CryptDestroyKey(key);
2783     CryptReleaseContext(prov,0);
2784     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2785     ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2786     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2787     ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2788     CryptDestroyKey(key);
2789     CryptReleaseContext(prov, 0);
2790
2791     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2792      CRYPT_DELETEKEYSET);
2793
2794     /* test the machine key set */
2795     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2796      CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2797     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2798      CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2799     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2800     CryptReleaseContext(prov, 0);
2801     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2802      CRYPT_MACHINE_KEYSET);
2803     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2804     CryptReleaseContext(prov,0);
2805     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2806        CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2807     ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2808                 GetLastError());
2809     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2810      CRYPT_MACHINE_KEYSET);
2811     ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2812         "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2813
2814 }
2815
2816 static void test_key_permissions(void)
2817 {
2818     HCRYPTKEY hKey1, hKey2;
2819     DWORD dwVal, dwLen;
2820     BOOL result;
2821
2822     /* Create keys that are exportable */
2823     if (!init_base_environment(CRYPT_EXPORTABLE))
2824         return;
2825
2826     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2827     ok (result, "%08x\n", GetLastError());
2828     if (!result) return;
2829
2830     dwVal = 0xdeadbeef;
2831     dwLen = sizeof(DWORD);
2832     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2833     ok(result, "%08x\n", GetLastError());
2834     ok(dwVal ==
2835         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2836         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2837         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2838         " got %08x\n", dwVal);
2839
2840     /* The key exchange key's public key may be exported.. */
2841     result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2842     ok(result, "%08x\n", GetLastError());
2843     /* and its private key may be too. */
2844     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2845     ok(result, "%08x\n", GetLastError());
2846     /* Turning off the key's export permissions is "allowed".. */
2847     dwVal &= ~CRYPT_EXPORT;
2848     result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2849     ok(result ||
2850         broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2851         broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2852         "%08x\n", GetLastError());
2853     /* but it has no effect. */
2854     dwVal = 0xdeadbeef;
2855     dwLen = sizeof(DWORD);
2856     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2857     ok(result, "%08x\n", GetLastError());
2858     ok(dwVal ==
2859         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2860         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2861         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2862         " got %08x\n", dwVal);
2863     /* Thus, changing the export flag of the key doesn't affect whether the key
2864      * may be exported.
2865      */
2866     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2867     ok(result, "%08x\n", GetLastError());
2868
2869     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2870     ok (result, "%08x\n", GetLastError());
2871
2872     /* A subsequent get of the same key, into a different handle, also doesn't
2873      * show that the permissions have been changed.
2874      */
2875     dwVal = 0xdeadbeef;
2876     dwLen = sizeof(DWORD);
2877     result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2878     ok(result, "%08x\n", GetLastError());
2879     ok(dwVal ==
2880         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2881         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2882         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2883         " got %08x\n", dwVal);
2884
2885     CryptDestroyKey(hKey2);
2886     CryptDestroyKey(hKey1);
2887
2888     clean_up_base_environment();
2889 }
2890
2891 static void test_key_initialization(void)
2892 {
2893     DWORD dwLen;
2894     HCRYPTPROV prov1, prov2;
2895     HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2896     BOOL result;
2897     static BYTE abSessionKey[148] = {
2898         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2899         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2900         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2901         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2902         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2903         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2904         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2905         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2906         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2907         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2908         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2909         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2910         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2911         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2912         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2913         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2914         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2915         0x04, 0x8c, 0x49, 0x92
2916     };
2917
2918     /* Like init_base_environment, but doesn't generate new keys, as they'll
2919      * be imported instead.
2920      */
2921     if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2922     {
2923         result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2924                                      CRYPT_NEWKEYSET);
2925         ok(result, "%08x\n", GetLastError());
2926     }
2927     dwLen = (DWORD)sizeof(abPlainPrivateKey);
2928     result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2929
2930     dwLen = (DWORD)sizeof(abSessionKey);
2931     result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2932     ok(result, "%08x\n", GetLastError());
2933
2934     /* Once the key has been imported, subsequently acquiring a context with
2935      * the same name will allow retrieving the key.
2936      */
2937     result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2938     ok(result, "%08x\n", GetLastError());
2939     result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2940     ok(result, "%08x\n", GetLastError());
2941     if (result) CryptDestroyKey(hKey);
2942     CryptReleaseContext(prov2, 0);
2943
2944     CryptDestroyKey(hSessionKey);
2945     CryptDestroyKey(hKeyExchangeKey);
2946     CryptReleaseContext(prov1, 0);
2947     CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2948      CRYPT_DELETEKEYSET);
2949 }
2950
2951 START_TEST(rsaenh)
2952 {
2953     if (!init_base_environment(0))
2954         return;
2955     test_prov();
2956     test_gen_random();
2957     test_hashes();
2958     test_rc4();
2959     test_rc2();
2960     test_des();
2961     test_3des112();
2962     test_3des();
2963     test_hmac();
2964     test_mac();
2965     test_block_cipher_modes();
2966     test_import_private();
2967     test_verify_signature();
2968     test_rsa_encrypt();
2969     test_import_export();
2970     test_import_hmac();
2971     test_enum_container();
2972     clean_up_base_environment();
2973     test_key_permissions();
2974     test_key_initialization();
2975     test_schannel_provider();
2976     test_null_provider();
2977     test_rsa_round_trip();
2978     if (!init_aes_environment())
2979         return;
2980     test_aes(128);
2981     test_aes(192);
2982     test_aes(256);
2983     test_sha2();
2984     clean_up_aes_environment();
2985 }