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