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