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