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