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