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