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