rsaenh: Add support for mandatory parameters to RSAENH_CPGetProvParam.
[wine] / dlls / rsaenh / tests / rsaenh.c
1 /*
2  * Unit tests for rsaenh functions
3  *
4  * Copyright (c) 2004 Michael Jung
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <string.h>
22 #include <stdio.h>
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "wincrypt.h"
28
29 static HCRYPTPROV hProv;
30 static const char szContainer[] = "winetest";
31 static const unsigned char pbData[] = "Wine rocks totally!";
32 static const char szProvider[] = MS_ENHANCED_PROV_A;
33
34 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
35
36 /*
37 static void trace_hex(BYTE *pbData, DWORD dwLen) {
38     char szTemp[256];
39     DWORD i, j;
40
41     for (i = 0; i < dwLen-7; i+=8) {
42         sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", 
43             pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5], 
44             pbData[i+6], pbData[i+7]);
45         trace(szTemp);
46     }
47     for (j=0; i<dwLen; j++,i++) {
48         sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
49     }
50     trace(szTemp);
51 }
52 */
53
54 static int init_environment(void)
55 {
56     HCRYPTKEY hKey;
57     BOOL result;
58         
59     pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
60         
61     hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
62
63     result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
64     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
65     
66     if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
67     {
68         ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
69         if (GetLastError()!=NTE_BAD_KEYSET) return 0;
70         result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 
71                                     CRYPT_NEWKEYSET);
72         ok(result, "%08x\n", GetLastError());
73         if (!result) return 0;
74         result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
75         ok(result, "%08x\n", GetLastError());
76         if (result) CryptDestroyKey(hKey);
77         result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
78         ok(result, "%08x\n", GetLastError());
79         if (result) CryptDestroyKey(hKey);
80     }
81     return 1;
82 }
83
84 static void clean_up_environment(void)
85 {
86     BOOL result;
87
88     result = CryptReleaseContext(hProv, 1);
89     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
90         
91     CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
92 }
93
94 static void test_prov(void) 
95 {
96     BOOL result;
97     DWORD dwLen, dwInc;
98     
99     dwLen = (DWORD)sizeof(DWORD);
100     result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
101     ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
102     
103     dwLen = (DWORD)sizeof(DWORD);
104     result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
105     ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
106 }
107
108 static void test_gen_random(void)
109 {
110     BOOL result;
111     BYTE rnd1[16], rnd2[16];
112
113     memset(rnd1, 0, sizeof(rnd1));
114     memset(rnd2, 0, sizeof(rnd2));
115
116     result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
117     if (!result && GetLastError() == NTE_FAIL) {
118         /* rsaenh compiled without OpenSSL */
119         return;
120     }
121     
122     ok(result, "%08x\n", GetLastError());
123
124     result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
125     ok(result, "%08x\n", GetLastError());
126
127     ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
128 }
129
130 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len) 
131 {
132     HCRYPTHASH hHash;
133     BOOL result;
134     unsigned char pbData[2000];
135     int i;
136
137     *phKey = (HCRYPTKEY)NULL;
138     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
139     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
140     if (!result) {
141         /* rsaenh compiled without OpenSSL */
142         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
143         return FALSE;
144     } 
145     ok(result, "%08x\n", GetLastError());
146     if (!result) return FALSE;
147     result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
148     ok(result, "%08x\n", GetLastError());
149     if (!result) return FALSE;
150     result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
151     ok(result, "%08x\n", GetLastError());
152     if (!result) return FALSE;
153     len = 2000;
154     result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
155     ok(result, "%08x\n", GetLastError());
156     CryptDestroyHash(hHash);
157     return TRUE;
158 }
159
160 static void test_hashes(void)
161 {
162     static const unsigned char md2hash[16] = {
163         0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9, 
164         0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
165     static const unsigned char md4hash[16] = {
166         0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23, 
167         0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
168     static const unsigned char md5hash[16] = { 
169         0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd, 
170         0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };    
171     static const unsigned char sha1hash[20] = { 
172         0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d, 
173         0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
174     unsigned char pbData[2048];
175     BOOL result;
176     HCRYPTHASH hHash, hHashClone;
177     BYTE pbHashValue[36];
178     DWORD hashlen, len;
179     int i;
180
181     for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
182
183     /* MD2 Hashing */
184     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
185     if (!result) {
186         /* rsaenh compiled without OpenSSL */
187         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
188     } else {
189         result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
190         ok(result, "%08x\n", GetLastError());
191
192         len = sizeof(DWORD);
193         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
194            ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
195
196         len = 16;
197         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
198         ok(result, "%08x\n", GetLastError());
199
200         ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
201
202         result = CryptDestroyHash(hHash);
203         ok(result, "%08x\n", GetLastError());
204     } 
205
206     /* MD4 Hashing */
207     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
208     ok(result, "%08x\n", GetLastError());
209
210     result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
211     ok(result, "%08x\n", GetLastError());
212
213     len = sizeof(DWORD);
214     result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
215     ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
216
217     len = 16;
218     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
219     ok(result, "%08x\n", GetLastError());
220
221     ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
222
223     result = CryptDestroyHash(hHash);
224     ok(result, "%08x\n", GetLastError());
225
226     /* MD5 Hashing */
227     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
228     ok(result, "%08x\n", GetLastError());
229
230     result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
231     ok(result, "%08x\n", GetLastError());
232
233     len = sizeof(DWORD);
234     result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
235     ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
236
237     len = 16;
238     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
239     ok(result, "%08x\n", GetLastError());
240
241     ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
242
243     result = CryptDestroyHash(hHash);
244     ok(result, "%08x\n", GetLastError());
245
246     /* SHA1 Hashing */
247     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
248     ok(result, "%08x\n", GetLastError());
249
250     result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
251     ok(result, "%08x\n", GetLastError());
252
253     if(pCryptDuplicateHash) {
254         result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
255         ok(result, "%08x\n", GetLastError());
256
257         result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
258         ok(result, "%08x\n", GetLastError());
259
260         len = sizeof(DWORD);
261         result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
262         ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
263
264         len = 20;
265         result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
266         ok(result, "%08x\n", GetLastError());
267
268         ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
269
270         result = CryptDestroyHash(hHashClone);
271         ok(result, "%08x\n", GetLastError());
272     }
273
274     result = CryptDestroyHash(hHash);
275     ok(result, "%08x\n", GetLastError());
276 }
277
278 static void test_block_cipher_modes(void)
279 {
280     static const BYTE plain[23] = { 
281         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 
282         0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
283     static const BYTE ecb[24] = {   
284         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f, 
285         0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
286     static const BYTE cbc[24] = {   
287         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
288         0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
289     static const BYTE cfb[24] = {   
290         0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
291         0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
292     HCRYPTKEY hKey;
293     BOOL result;
294     BYTE abData[24];
295     DWORD dwMode, dwLen;
296
297     result = derive_key(CALG_RC2, &hKey, 40);
298     if (!result) return;
299
300     memcpy(abData, plain, sizeof(abData));
301
302     dwMode = CRYPT_MODE_ECB;
303     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
304     ok(result, "%08x\n", GetLastError());
305
306     dwLen = 23;
307     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
308     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
309     ok(dwLen == 24, "Unexpected length %d\n", dwLen);
310
311     SetLastError(ERROR_SUCCESS);
312     dwLen = 23;
313     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
314     ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)), 
315        "%08x, dwLen: %d\n", GetLastError(), dwLen);
316
317     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
318     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)), 
319        "%08x, dwLen: %d\n", GetLastError(), dwLen);
320
321     dwMode = CRYPT_MODE_CBC;
322     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
323     ok(result, "%08x\n", GetLastError());
324     
325     dwLen = 23;
326     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
327     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
328     ok(dwLen == 24, "Unexpected length %d\n", dwLen);
329
330     dwLen = 23;
331     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
332     ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)), 
333        "%08x, dwLen: %d\n", GetLastError(), dwLen);
334
335     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
336     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)), 
337        "%08x, dwLen: %d\n", GetLastError(), dwLen);
338
339     dwMode = CRYPT_MODE_CFB;
340     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
341     ok(result, "%08x\n", GetLastError());
342     
343     dwLen = 16;
344     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
345     ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
346
347     dwLen = 7;
348     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
349     ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)), 
350        "%08x, dwLen: %d\n", GetLastError(), dwLen);
351     
352     dwLen = 8;
353     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
354     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
355
356     dwLen = 16;
357     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
358     ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)), 
359        "%08x, dwLen: %d\n", GetLastError(), dwLen);
360
361     dwMode = CRYPT_MODE_OFB;
362     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
363     ok(result, "%08x\n", GetLastError());
364     
365     dwLen = 23;
366     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
367     ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
368 }
369
370 static void test_3des112(void)
371 {
372     HCRYPTKEY hKey;
373     BOOL result;
374     DWORD dwLen;
375     unsigned char pbData[16];
376     int i;
377
378     result = derive_key(CALG_3DES_112, &hKey, 0);
379     if (!result) {
380         /* rsaenh compiled without OpenSSL */
381         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
382         return;
383     }
384
385     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
386     
387     dwLen = 13;
388     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
389     ok(result, "%08x\n", GetLastError());
390     
391     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
392     ok(result, "%08x\n", GetLastError());
393
394     result = CryptDestroyKey(hKey);
395     ok(result, "%08x\n", GetLastError());
396 }
397
398 static void test_des(void) 
399 {
400     HCRYPTKEY hKey;
401     BOOL result;
402     DWORD dwLen, dwMode;
403     unsigned char pbData[16];
404     int i;
405
406     result = derive_key(CALG_DES, &hKey, 56);
407     if (!result) {
408         /* rsaenh compiled without OpenSSL */
409         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
410         return;
411     }
412
413     dwMode = CRYPT_MODE_ECB;
414     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
415     ok(result, "%08x\n", GetLastError());
416     
417     dwLen = sizeof(DWORD);
418     result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
419     ok(result, "%08x\n", GetLastError());
420     
421     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
422     
423     dwLen = 13;
424     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
425     ok(result, "%08x\n", GetLastError());
426     
427     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
428     ok(result, "%08x\n", GetLastError());
429
430     result = CryptDestroyKey(hKey);
431     ok(result, "%08x\n", GetLastError());
432 }
433
434 static void test_3des(void)
435 {
436     HCRYPTKEY hKey;
437     BOOL result;
438     DWORD dwLen;
439     unsigned char pbData[16];
440     static const BYTE des3[16] = { 
441         0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3, 
442         0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
443     int i;
444
445     result = derive_key(CALG_3DES, &hKey, 0);
446     if (!result) return;
447
448     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
449     
450     dwLen = 13;
451     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
452     ok(result, "%08x\n", GetLastError());
453     
454     ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
455     
456     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
457     ok(result, "%08x\n", GetLastError());
458
459     result = CryptDestroyKey(hKey);
460     ok(result, "%08x\n", GetLastError());
461 }
462
463 static void test_rc2(void)
464 {
465     static const BYTE rc2encrypted[16] = { 
466         0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b, 
467         0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
468     HCRYPTHASH hHash;
469     HCRYPTKEY hKey;
470     BOOL result;
471     DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
472     BYTE *pbTemp;
473     unsigned char pbData[2000], pbHashValue[16];
474     int i;
475     
476     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
477
478     /* MD2 Hashing */
479     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
480     if (!result) {
481         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
482     } else {
483         result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
484         ok(result, "%08x\n", GetLastError());
485
486         dwLen = 16;
487         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
488         ok(result, "%08x\n", GetLastError());
489
490         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
491         ok(result, "%08x\n", GetLastError());
492
493         dwLen = sizeof(DWORD);
494         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
495         ok(result, "%08x\n", GetLastError());
496
497         dwMode = CRYPT_MODE_CBC;
498         result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
499         ok(result, "%08x\n", GetLastError());
500
501         dwLen = sizeof(DWORD);
502         result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
503         ok(result, "%08x\n", GetLastError());
504
505         dwLen = sizeof(DWORD);
506         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
507         ok(result, "%08x\n", GetLastError());
508
509         dwLen = sizeof(DWORD);
510         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
511         ok(result, "%08x\n", GetLastError());
512
513         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
514         ok(result, "%08x\n", GetLastError());
515         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
516         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
517         HeapFree(GetProcessHeap(), 0, pbTemp);
518
519         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
520         ok(result, "%08x\n", GetLastError());
521         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
522         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
523         HeapFree(GetProcessHeap(), 0, pbTemp);
524
525         dwLen = sizeof(DWORD);
526         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
527
528         result = CryptDestroyHash(hHash);
529         ok(result, "%08x\n", GetLastError());
530
531         dwDataLen = 13;
532         result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
533         ok(result, "%08x\n", GetLastError());
534
535         ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
536
537         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
538         ok(result, "%08x\n", GetLastError());
539         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
540         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
541         HeapFree(GetProcessHeap(), 0, pbTemp);
542
543         result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
544         ok(result, "%08x\n", GetLastError());
545
546         result = CryptDestroyKey(hKey);
547         ok(result, "%08x\n", GetLastError());
548     }
549 }
550
551 static void test_rc4(void)
552 {
553     static const BYTE rc4[16] = { 
554         0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0, 
555         0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };    
556     BOOL result;
557     HCRYPTHASH hHash;
558     HCRYPTKEY hKey;
559     DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
560     unsigned char pbData[2000], *pbTemp;
561     unsigned char pszBuffer[256];
562     int i;
563
564     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
565
566     /* MD2 Hashing */
567     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
568     if (!result) {
569         /* rsaenh compiled without OpenSSL */
570         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
571     } else {
572         result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
573            ok(result, "%08x\n", GetLastError());
574
575         dwLen = 16;
576         result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
577         ok(result, "%08x\n", GetLastError());
578
579         result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
580         ok(result, "%08x\n", GetLastError());
581
582         dwLen = sizeof(DWORD);
583         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
584         ok(result, "%08x\n", GetLastError());
585
586         dwLen = sizeof(DWORD);
587         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
588         ok(result, "%08x\n", GetLastError());
589
590         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
591         ok(result, "%08x\n", GetLastError());
592         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
593         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
594         HeapFree(GetProcessHeap(), 0, pbTemp);
595
596         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
597         ok(result, "%08x\n", GetLastError());
598         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
599         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
600         HeapFree(GetProcessHeap(), 0, pbTemp);
601
602         dwLen = sizeof(DWORD);
603         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
604
605         result = CryptDestroyHash(hHash);
606         ok(result, "%08x\n", GetLastError());
607
608         dwDataLen = 16;
609         result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
610         ok(result, "%08x\n", GetLastError());
611         dwDataLen = 16;
612         result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
613         ok(result, "%08x\n", GetLastError());
614
615         ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
616
617         result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
618         ok(result, "%08x\n", GetLastError());
619
620         result = CryptDestroyKey(hKey);
621         ok(result, "%08x\n", GetLastError());
622     }
623 }
624
625 static void test_hmac(void) {
626     HCRYPTKEY hKey;
627     HCRYPTHASH hHash;
628     BOOL result;
629     /* Using CALG_MD2 here fails on Windows 2003, why ? */
630     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
631     DWORD dwLen;
632     BYTE abData[256];
633     static const BYTE hmac[16] = { 
634         0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c, 
635         0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
636     int i;
637
638     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
639
640     if (!derive_key(CALG_RC2, &hKey, 56)) return;
641
642     result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
643     ok(result, "%08x\n", GetLastError());
644     if (!result) return;
645
646     result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
647     ok(result, "%08x\n", GetLastError());
648
649     result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
650     ok(result, "%08x\n", GetLastError());
651
652     dwLen = sizeof(abData)/sizeof(BYTE);
653     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
654     ok(result, "%08x\n", GetLastError());
655
656     ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
657     
658     result = CryptDestroyHash(hHash);
659     ok(result, "%08x\n", GetLastError());
660     
661     result = CryptDestroyKey(hKey);
662     ok(result, "%08x\n", GetLastError());
663
664     /* Provoke errors */
665     result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
666     ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
667 }
668
669 static void test_mac(void) {
670     HCRYPTKEY hKey;
671     HCRYPTHASH hHash;
672     BOOL result;
673     DWORD dwLen;
674     BYTE abData[256], abEnc[264];
675     static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
676     int i;
677
678     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
679     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
680
681     if (!derive_key(CALG_RC2, &hKey, 56)) return;
682
683     dwLen = 256;
684     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
685     ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
686     
687     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
688     ok(result, "%08x\n", GetLastError());
689     if (!result) return;
690
691     result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
692     ok(result, "%08x\n", GetLastError());
693
694     dwLen = sizeof(abData)/sizeof(BYTE);
695     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
696     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
697
698     ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
699     
700     result = CryptDestroyHash(hHash);
701     ok(result, "%08x\n", GetLastError());
702     
703     result = CryptDestroyKey(hKey);
704     ok(result, "%08x\n", GetLastError());
705     
706     /* Provoke errors */
707     if (!derive_key(CALG_RC4, &hKey, 56)) return;
708
709     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
710     ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
711
712     result = CryptDestroyKey(hKey);
713     ok(result, "%08x\n", GetLastError());
714 }
715
716 static BYTE abPlainPrivateKey[596] = {
717     0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
718     0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
719     0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
720     0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
721     0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
722     0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
723     0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
724     0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
725     0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
726     0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
727     0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
728     0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
729     0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
730     0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
731     0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
732     0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
733     0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
734     0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
735     0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
736     0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
737     0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
738     0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
739     0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
740     0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
741     0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
742     0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
743     0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
744     0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
745     0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
746     0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
747     0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
748     0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
749     0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
750     0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
751     0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
752     0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
753     0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
754     0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
755     0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
756     0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
757     0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
758     0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
759     0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
760     0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
761     0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
762     0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
763     0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
764     0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
765     0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
766     0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
767     0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
768     0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
769     0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
770     0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
771     0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
772     0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
773     0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
774     0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
775     0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
776     0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
777     0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
778     0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
779     0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
780     0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
781     0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
782     0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
783     0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
784     0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
785     0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
786     0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
787     0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
788     0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
789     0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
790     0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
791     0xf2, 0x5d, 0x58, 0x07
792 };
793
794 static void test_import_private(void) 
795 {
796     DWORD dwLen;
797     HCRYPTKEY hKeyExchangeKey, hSessionKey;
798     BOOL result;
799     static BYTE abSessionKey[148] = {
800         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
801         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
802         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
803         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
804         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
805         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
806         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
807         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
808         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
809         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
810         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
811         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
812         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
813         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
814         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
815         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
816         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
817         0x04, 0x8c, 0x49, 0x92
818     };
819     static BYTE abEncryptedMessage[12] = {
820         0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
821         0x1c, 0xfd, 0xde, 0x71
822     };
823             
824     dwLen = (DWORD)sizeof(abPlainPrivateKey);
825     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
826     if (!result) {
827         /* rsaenh compiled without OpenSSL */
828         ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
829         return;
830     }
831
832     dwLen = (DWORD)sizeof(abSessionKey);
833     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
834     ok(result, "%08x\n", GetLastError());
835     if (!result) return;
836
837     dwLen = (DWORD)sizeof(abEncryptedMessage);
838     result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
839     ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12), 
840        "%08x, len: %d\n", GetLastError(), dwLen);
841     
842     if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
843
844     dwLen = (DWORD)sizeof(abSessionKey);
845     result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
846     ok(result, "%08x\n", GetLastError());
847     if (!result) return;
848
849     dwLen = (DWORD)sizeof(abSessionKey);
850     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
851     ok(result, "%08x\n", GetLastError());
852     if (!result) return;
853 }
854
855 static void test_verify_signature(void) {
856     HCRYPTHASH hHash;
857     HCRYPTKEY hPubSignKey;
858     BYTE abData[] = "Wine rocks!";
859     BOOL result;
860     BYTE abPubKey[148] = {
861         0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 
862         0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 
863         0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19, 
864         0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27, 
865         0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8, 
866         0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda, 
867         0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a, 
868         0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc, 
869         0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c, 
870         0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c, 
871         0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89, 
872         0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b, 
873         0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa, 
874         0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63, 
875         0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff, 
876         0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49, 
877         0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87, 
878         0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7, 
879         0xe1, 0x21, 0x50, 0xac
880     };
881     /* md2 with hash oid */
882     BYTE abSignatureMD2[128] = {
883         0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67, 
884         0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b, 
885         0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda, 
886         0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59, 
887         0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a, 
888         0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34, 
889         0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40, 
890         0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7, 
891         0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0, 
892         0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06, 
893         0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51, 
894         0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f, 
895         0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46, 
896         0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25, 
897         0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0, 
898         0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
899     };
900     /* md2 without hash oid */
901     BYTE abSignatureMD2NoOID[128] = {
902         0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d, 
903         0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19, 
904         0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd, 
905         0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4, 
906         0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65, 
907         0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99, 
908         0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf, 
909         0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc, 
910         0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0, 
911         0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01, 
912         0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7, 
913         0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f, 
914         0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a, 
915         0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9, 
916         0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06, 
917         0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
918     };
919     /* md4 with hash oid */
920     BYTE abSignatureMD4[128] = {
921         0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51, 
922         0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b, 
923         0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2, 
924         0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e, 
925         0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13, 
926         0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9, 
927         0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f, 
928         0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96, 
929         0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9, 
930         0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e, 
931         0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0, 
932         0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe, 
933         0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18, 
934         0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab, 
935         0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3, 
936         0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
937     };
938     /* md4 without hash oid */
939     BYTE abSignatureMD4NoOID[128] = {
940         0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda, 
941         0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24, 
942         0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0, 
943         0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36, 
944         0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85, 
945         0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3, 
946         0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f, 
947         0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9, 
948         0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06, 
949         0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f, 
950         0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb, 
951         0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96, 
952         0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f, 
953         0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9, 
954         0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb, 
955         0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
956     }; 
957     /* md5 with hash oid */
958     BYTE abSignatureMD5[128] = {
959         0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5, 
960         0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f, 
961         0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7, 
962         0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98, 
963         0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec, 
964         0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5, 
965         0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04, 
966         0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b, 
967         0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95, 
968         0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c, 
969         0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29, 
970         0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9, 
971         0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c, 
972         0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90, 
973         0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e, 
974         0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
975     };
976     /* md5 without hash oid */
977     BYTE abSignatureMD5NoOID[128] = {
978         0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f, 
979         0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75, 
980         0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f, 
981         0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d, 
982         0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f, 
983         0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49, 
984         0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8, 
985         0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c, 
986         0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23, 
987         0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19, 
988         0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb, 
989         0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3, 
990         0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b, 
991         0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b, 
992         0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5, 
993         0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
994     };
995     /* sha with hash oid */
996     BYTE abSignatureSHA[128] = {
997         0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91, 
998         0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd, 
999         0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24, 
1000         0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94, 
1001         0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f, 
1002         0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a, 
1003         0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52, 
1004         0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20, 
1005         0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5, 
1006         0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a, 
1007         0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff, 
1008         0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53, 
1009         0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00, 
1010         0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e, 
1011         0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98, 
1012         0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1013     };
1014     /* sha without hash oid */
1015     BYTE abSignatureSHANoOID[128] = {
1016         0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6, 
1017         0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a, 
1018         0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f, 
1019         0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37, 
1020         0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65, 
1021         0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe, 
1022         0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6, 
1023         0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe, 
1024         0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c, 
1025         0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4, 
1026         0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80, 
1027         0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a, 
1028         0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00, 
1029         0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd, 
1030         0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67, 
1031         0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1032     }; 
1033     
1034     result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1035     ok(result, "%08x\n", GetLastError());
1036     if (!result) return;
1037
1038     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1039     ok(result, "%08x\n", GetLastError());
1040     if (!result) return;
1041
1042     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1043     ok(result, "%08x\n", GetLastError());
1044     if (!result) return;
1045
1046     result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1047     ok(result, "%08x\n", GetLastError());
1048     if (!result) return;
1049
1050     result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1051     ok(result, "%08x\n", GetLastError());
1052     if (!result) return;
1053
1054     /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about 
1055      * the OID at all. */
1056     /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1057     ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1058     if (result) return;*/
1059
1060     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1061     ok(result, "%08x\n", GetLastError());
1062     if (!result) return;
1063
1064     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1065     ok(result, "%08x\n", GetLastError());
1066     if (!result) return;
1067
1068     result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1069     ok(result, "%08x\n", GetLastError());
1070     if (!result) return;
1071
1072     result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1073     ok(result, "%08x\n", GetLastError());
1074     if (!result) return;
1075
1076     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1077     ok(result, "%08x\n", GetLastError());
1078     if (!result) return;
1079
1080     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1081     ok(result, "%08x\n", GetLastError());
1082     if (!result) return;
1083
1084     result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1085     ok(result, "%08x\n", GetLastError());
1086     if (!result) return;
1087
1088     result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1089     ok(result, "%08x\n", GetLastError());
1090     if (!result) return;
1091
1092     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1093     ok(result, "%08x\n", GetLastError());
1094     if (!result) return;
1095
1096     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1097     ok(result, "%08x\n", GetLastError());
1098     if (!result) return;
1099
1100     result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1101     ok(result, "%08x\n", GetLastError());
1102     if (!result) return;
1103
1104     result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1105     ok(result, "%08x\n", GetLastError());
1106     if (!result) return;
1107 }
1108
1109 static void test_rsa_encrypt(void)
1110 {
1111     HCRYPTKEY hRSAKey;
1112     BYTE abData[2048] = "Wine rocks!";
1113     BOOL result;
1114     DWORD dwLen;
1115
1116     /* It is allowed to use the key exchange key for encryption/decryption */
1117     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1118     ok (result, "%08x\n", GetLastError());
1119     if (!result) return;
1120
1121     dwLen = 12;
1122     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1123     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1124     ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1125     dwLen = 12;
1126     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1127     ok (result, "%08x\n", GetLastError());
1128     if (!result) return;
1129
1130     result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1131     ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1132     
1133     CryptDestroyKey(hRSAKey);
1134
1135     /* It is not allowed to use the signature key for encryption/decryption */
1136     result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1137     ok (result, "%08x\n", GetLastError());
1138     if (!result) return;
1139
1140     dwLen = 12;
1141     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1142     ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1143
1144     CryptDestroyKey(hRSAKey);
1145 }
1146
1147 static void test_import_export(void)
1148 {
1149     DWORD dwLen, dwDataLen;
1150     HCRYPTKEY hPublicKey;
1151     BOOL result;
1152     ALG_ID algID;
1153     BYTE emptyKey[2048];
1154     static BYTE abPlainPublicKey[84] = {
1155         0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1156         0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1157         0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1158         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1159         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1160         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1161         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1162         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1163         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1164         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1165         0x11, 0x11, 0x11, 0x11
1166     };
1167
1168     dwLen=84;
1169     result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1170     ok(result, "failed to import the public key\n");
1171
1172     dwDataLen=sizeof(algID);
1173     result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1174     ok(result, "failed to get the KP_ALGID from the imported public key\n");
1175     ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1176         
1177     result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1178     ok(result, "failed to export the fresh imported public key\n");
1179     ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1180     ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1181 }
1182         
1183 static void test_schannel_provider(void)
1184 {
1185     HCRYPTPROV hProv;
1186     HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1187     HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1188     BOOL result;
1189     DWORD dwLen;
1190     SCHANNEL_ALG saSChannelAlg;
1191     CRYPT_DATA_BLOB data_blob;
1192     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1193     BYTE abPlainPrivateKey[596] = {
1194         0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1195         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1196         0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1197         0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1198         0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1199         0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1200         0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1201         0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1202         0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1203         0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1204         0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1205         0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1206         0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1207         0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1208         0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1209         0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1210         0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1211         0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1212         0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1213         0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1214         0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1215         0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1216         0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1217         0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1218         0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1219         0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1220         0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1221         0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1222         0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1223         0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1224         0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1225         0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1226         0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1227         0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1228         0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1229         0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1230         0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1231         0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1232         0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1233         0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1234         0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1235         0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1236         0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1237         0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1238         0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1239         0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1240         0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1241         0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1242         0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1243         0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1244         0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1245         0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1246         0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1247         0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1248         0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1249         0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1250         0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1251         0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1252         0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1253         0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1254         0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1255         0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1256         0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1257         0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1258         0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1259         0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1260         0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1261         0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1262         0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1263         0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1264         0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1265         0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1266         0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1267         0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1268         0xf2, 0x5d, 0x58, 0x07
1269     };
1270     BYTE abTLS1Master[140] = {
1271         0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00, 
1272         0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68, 
1273         0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97, 
1274         0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53, 
1275         0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24, 
1276         0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3, 
1277         0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8, 
1278         0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d, 
1279         0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e, 
1280         0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e, 
1281         0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40, 
1282         0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b, 
1283         0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb, 
1284         0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6, 
1285         0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac, 
1286         0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41, 
1287         0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4, 
1288         0xd3, 0x1e, 0x82, 0xb3
1289     };
1290     BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1291     BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1292     BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1293     BYTE abClientFinished[16] = "client finished";
1294     BYTE abData[16] = "Wine rocks!";
1295     BYTE abMD5Hash[16];
1296     static const BYTE abEncryptedData[16] = {
1297         0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1298         0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d    
1299     };
1300     static const BYTE abPRF[16] = {
1301         0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1302         0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1303     };
1304     static const BYTE abMD5[16] = {
1305         0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1306         0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1307     };
1308     
1309     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1310     ok (result, "%08x\n", GetLastError());
1311     if (!result) return;
1312     
1313     /* To get deterministic results, we import the TLS1 master secret (which
1314      * is typically generated from a random generator). Therefore, we need
1315      * an RSA key. */
1316     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1317     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1318     ok (result, "%08x\n", GetLastError());
1319     if (!result) return;
1320
1321     dwLen = (DWORD)sizeof(abTLS1Master);
1322     result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1323     ok (result, "%08x\n", GetLastError());
1324     if (!result) return;    
1325    
1326     /* Setting the TLS1 client and server random parameters, as well as the 
1327      * MAC and encryption algorithm parameters. */
1328     data_blob.cbData = 33;
1329     data_blob.pbData = abClientSecret;
1330     result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1331     ok (result, "%08x\n", GetLastError());
1332     if (!result) return;
1333
1334     data_blob.cbData = 33;
1335     data_blob.pbData = abServerSecret;
1336     result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1337     ok (result, "%08x\n", GetLastError());
1338     if (!result) return;
1339     
1340     saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1341     saSChannelAlg.Algid = CALG_DES;
1342     saSChannelAlg.cBits = 64;
1343     saSChannelAlg.dwFlags = 0;
1344     saSChannelAlg.dwReserved = 0;
1345     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1346     ok (result, "%08x\n", GetLastError());
1347     if (!result) return;
1348
1349     saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1350     saSChannelAlg.Algid = CALG_MD5;
1351     saSChannelAlg.cBits = 128;
1352     saSChannelAlg.dwFlags = 0;
1353     saSChannelAlg.dwReserved = 0;
1354     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1355     ok (result, "%08x\n", GetLastError());
1356     if (!result) return;
1357
1358     /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1359      * (Keys can only be derived from hashes, not from other keys.) */
1360     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1361     ok (result, "%08x\n", GetLastError());
1362     if (!result) return;
1363
1364     /* Deriving the server write encryption key from the master hash */
1365     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1366     ok (result, "%08x\n", GetLastError());
1367     if (!result) return;
1368
1369     /* Encrypting some data with the server write encryption key and checking the result. */
1370     dwLen = 12;
1371     result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1372     ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1373
1374     /* Second test case: Test the TLS1 pseudo random number function. */
1375     result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1376     ok (result, "%08x\n", GetLastError());
1377     if (!result) return;
1378
1379     /* Set the label and seed parameters for the random number function */
1380     data_blob.cbData = 36;
1381     data_blob.pbData = abHashedHandshakes;
1382     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1383     ok (result, "%08x\n", GetLastError());
1384     if (!result) return;
1385
1386     data_blob.cbData = 15;
1387     data_blob.pbData = abClientFinished;
1388     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1389     ok (result, "%08x\n", GetLastError());
1390     if (!result) return;
1391
1392     /* Generate some pseudo random bytes and check if they are correct. */
1393     dwLen = (DWORD)sizeof(abData);
1394     result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1395     ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)), 
1396         "%08x\n", GetLastError());
1397
1398     /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1399      * Hash some data with the HMAC. Compare results. */
1400     result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1401     ok (result, "%08x\n", GetLastError());
1402     if (!result) return;
1403     
1404     result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1405     ok (result, "%08x\n", GetLastError());
1406     if (!result) return;
1407
1408     result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1409     ok (result, "%08x\n", GetLastError());
1410     if (!result) return;
1411
1412     result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1413     ok (result, "%08x\n", GetLastError());
1414     if (!result) return;
1415
1416     dwLen = (DWORD)sizeof(abMD5Hash);
1417     result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1418     ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1419
1420     CryptDestroyHash(hHMAC);
1421     CryptDestroyHash(hTLS1PRF);
1422     CryptDestroyHash(hMasterHash);
1423     CryptDestroyKey(hServerWriteMACKey);
1424     CryptDestroyKey(hServerWriteKey);
1425     CryptDestroyKey(hRSAKey);
1426     CryptDestroyKey(hMasterSecret);
1427     CryptReleaseContext(hProv, 0);
1428     CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1429 }
1430
1431 static void test_enum_container(void)
1432 {
1433     BYTE abContainerName[256];
1434     DWORD dwBufferLen;
1435     BOOL result, fFound = FALSE;
1436
1437     /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1438      * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1439     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1440     ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1441
1442     /* If the result fits into abContainerName dwBufferLen is left untouched */
1443     dwBufferLen = (DWORD)sizeof(abContainerName);
1444     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1445     ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1446     
1447     /* We only check, if the currently open 'winetest' container is among the enumerated. */
1448     do {
1449         if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1450         dwBufferLen = (DWORD)sizeof(abContainerName);
1451     } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1452         
1453     ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1454 }
1455
1456 static BYTE signBlob[] = {
1457 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1458 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1459 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1460 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1461 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1462 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1463 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1464 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1465 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1466 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1467 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1468 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1469 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1470 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1471 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1472 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1473 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1474 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1475 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1476 0xb6,0x85,0x86,0x07 };
1477
1478 static void test_null_provider(void)
1479 {
1480     HCRYPTPROV prov;
1481     HCRYPTKEY key;
1482     BOOL result;
1483     DWORD keySpec, dataLen,dwParam;
1484     char szName[MAX_PATH];
1485
1486     result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1487     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1488      "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1489     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1490     ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1491      "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1492     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1493      CRYPT_DELETEKEYSET);
1494     ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1495      "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1496     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1497      CRYPT_DELETEKEYSET);
1498     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1499      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1500     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1501     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1502      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1503
1504     /* Delete the default container. */
1505     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1506     /* Once you've deleted the default container you can't open it as if it
1507      * already exists.
1508      */
1509     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1510     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1511      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1512     /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1513     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1514      CRYPT_VERIFYCONTEXT);
1515     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1516     if (!result) return;
1517     dataLen = sizeof(keySpec);
1518     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1519     if (result)
1520         ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1521          "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1522     /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1523      * supported, you can't get the keys from this container.
1524      */
1525     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1526     ok(!result && GetLastError() == NTE_NO_KEY,
1527      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1528     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1529     ok(!result && GetLastError() == NTE_NO_KEY,
1530      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1531     result = CryptReleaseContext(prov, 0);
1532     ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1533     /* You can create a new default container. */
1534     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1535      CRYPT_NEWKEYSET);
1536     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1537     /* But you still can't get the keys (until one's been generated.) */
1538     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1539     ok(!result && GetLastError() == NTE_NO_KEY,
1540      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1541     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1542     ok(!result && GetLastError() == NTE_NO_KEY,
1543      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1544     CryptReleaseContext(prov, 0);
1545     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1546
1547     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1548      CRYPT_DELETEKEYSET);
1549     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1550     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1551      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1552     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1553      CRYPT_VERIFYCONTEXT);
1554     ok(!result && GetLastError() == NTE_BAD_FLAGS,
1555      "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1556     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1557      CRYPT_NEWKEYSET);
1558     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1559     if (!result) return;
1560     /* Test provider parameters getter */
1561     dataLen = sizeof(dwParam);
1562     result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1563     ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1564         "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1565     dataLen = sizeof(dwParam);
1566     result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1567     ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1568         "Expected 0, got 0x%08X\n",dwParam);
1569     dataLen = sizeof(dwParam);
1570     result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1571     ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1572         "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1573     dataLen = sizeof(keySpec);
1574     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1575     ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1576         "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1577     /* PP_CONTAINER parameter */
1578     dataLen = sizeof(szName);
1579     result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1580     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1581         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1582         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1583     /* PP_UNIQUE_CONTAINER parameter */
1584     dataLen = sizeof(szName);
1585     result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1586     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1587         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1588         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1589     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1590     ok(!result && GetLastError() == NTE_NO_KEY,
1591      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1592     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1593     ok(!result && GetLastError() == NTE_NO_KEY,
1594      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1595
1596     /* Importing a key exchange blob.. */
1597     result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1598      0, 0, &key);
1599     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1600     CryptDestroyKey(key);
1601     /* allows access to the key exchange key.. */
1602     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1603     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1604     CryptDestroyKey(key);
1605     /* but not to the private key. */
1606     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1607     ok(!result && GetLastError() == NTE_NO_KEY,
1608      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1609     CryptReleaseContext(prov, 0);
1610     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1611      CRYPT_DELETEKEYSET);
1612
1613     /* Whereas importing a sign blob.. */
1614     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1615      CRYPT_NEWKEYSET);
1616     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1617     if (!result) return;
1618     result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1619     ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1620     /* doesn't allow access to the key exchange key.. */
1621     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1622     ok(!result && GetLastError() == NTE_NO_KEY,
1623      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1624     /* but does to the private key. */
1625     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1626     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1627     CryptDestroyKey(key);
1628
1629     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1630      CRYPT_DELETEKEYSET);
1631
1632
1633     /* test for the bug in accessing the user key in a container
1634      */
1635     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1636      CRYPT_NEWKEYSET);
1637     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1638     result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1639     ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1640     CryptDestroyKey(key);
1641     CryptReleaseContext(prov,0);
1642     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1643     ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1644     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1645     ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1646     CryptDestroyKey(key);
1647
1648     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1649      CRYPT_DELETEKEYSET);
1650
1651     /* test the machine key set */
1652     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1653      CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1654     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1655      CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1656     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1657     CryptReleaseContext(prov, 0);
1658     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1659      CRYPT_MACHINE_KEYSET);
1660     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1661     CryptReleaseContext(prov,0);
1662     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1663        CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1664     ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1665                 GetLastError());
1666     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1667      CRYPT_MACHINE_KEYSET);
1668     ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1669         "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1670
1671 }
1672
1673 START_TEST(rsaenh)
1674 {
1675     if (!init_environment()) 
1676         return;
1677     test_prov();
1678     test_gen_random();
1679     test_hashes();
1680     test_rc4();
1681     test_rc2();
1682     test_des();
1683     test_3des112();
1684     test_3des();
1685     test_hmac();
1686     test_mac();
1687     test_block_cipher_modes();
1688     test_import_private();
1689     test_verify_signature();
1690     test_rsa_encrypt();
1691     test_import_export();
1692     test_enum_container();
1693     clean_up_environment();
1694     test_schannel_provider();
1695     test_null_provider();
1696 }