d3drm: Implement D3DRMCreateColorRGB.
[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);
1322     ok (result, "%08x\n", GetLastError());
1323     if (!result) return;
1324     
1325     /* To get deterministic results, we import the TLS1 master secret (which
1326      * is typically generated from a random generator). Therefore, we need
1327      * an RSA key. */
1328     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1329     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1330     ok (result, "%08x\n", GetLastError());
1331     if (!result) return;
1332
1333     dwLen = (DWORD)sizeof(abTLS1Master);
1334     result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1335     ok (result, "%08x\n", GetLastError());
1336     if (!result) return;    
1337    
1338     /* Setting the TLS1 client and server random parameters, as well as the 
1339      * MAC and encryption algorithm parameters. */
1340     data_blob.cbData = 33;
1341     data_blob.pbData = abClientSecret;
1342     result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1343     ok (result, "%08x\n", GetLastError());
1344     if (!result) return;
1345
1346     data_blob.cbData = 33;
1347     data_blob.pbData = abServerSecret;
1348     result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1349     ok (result, "%08x\n", GetLastError());
1350     if (!result) return;
1351     
1352     saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1353     saSChannelAlg.Algid = CALG_DES;
1354     saSChannelAlg.cBits = 64;
1355     saSChannelAlg.dwFlags = 0;
1356     saSChannelAlg.dwReserved = 0;
1357     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1358     ok (result, "%08x\n", GetLastError());
1359     if (!result) return;
1360
1361     saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1362     saSChannelAlg.Algid = CALG_MD5;
1363     saSChannelAlg.cBits = 128;
1364     saSChannelAlg.dwFlags = 0;
1365     saSChannelAlg.dwReserved = 0;
1366     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1367     ok (result, "%08x\n", GetLastError());
1368     if (!result) return;
1369
1370     /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1371      * (Keys can only be derived from hashes, not from other keys.) */
1372     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1373     ok (result, "%08x\n", GetLastError());
1374     if (!result) return;
1375
1376     /* Deriving the server write encryption key from the master hash */
1377     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1378     ok (result, "%08x\n", GetLastError());
1379     if (!result) return;
1380
1381     /* Encrypting some data with the server write encryption key and checking the result. */
1382     dwLen = 12;
1383     result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1384     ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1385
1386     /* Second test case: Test the TLS1 pseudo random number function. */
1387     result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1388     ok (result, "%08x\n", GetLastError());
1389     if (!result) return;
1390
1391     /* Set the label and seed parameters for the random number function */
1392     data_blob.cbData = 36;
1393     data_blob.pbData = abHashedHandshakes;
1394     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1395     ok (result, "%08x\n", GetLastError());
1396     if (!result) return;
1397
1398     data_blob.cbData = 15;
1399     data_blob.pbData = abClientFinished;
1400     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1401     ok (result, "%08x\n", GetLastError());
1402     if (!result) return;
1403
1404     /* Generate some pseudo random bytes and check if they are correct. */
1405     dwLen = (DWORD)sizeof(abData);
1406     result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1407     ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)), 
1408         "%08x\n", GetLastError());
1409
1410     /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1411      * Hash some data with the HMAC. Compare results. */
1412     result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1413     ok (result, "%08x\n", GetLastError());
1414     if (!result) return;
1415     
1416     result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1417     ok (result, "%08x\n", GetLastError());
1418     if (!result) return;
1419
1420     result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1421     ok (result, "%08x\n", GetLastError());
1422     if (!result) return;
1423
1424     result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1425     ok (result, "%08x\n", GetLastError());
1426     if (!result) return;
1427
1428     dwLen = (DWORD)sizeof(abMD5Hash);
1429     result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1430     ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1431
1432     CryptDestroyHash(hHMAC);
1433     CryptDestroyHash(hTLS1PRF);
1434     CryptDestroyHash(hMasterHash);
1435     CryptDestroyKey(hServerWriteMACKey);
1436     CryptDestroyKey(hServerWriteKey);
1437     CryptDestroyKey(hRSAKey);
1438     CryptDestroyKey(hMasterSecret);
1439     CryptReleaseContext(hProv, 0);
1440     CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1441 }
1442
1443 static void test_enum_container(void)
1444 {
1445     BYTE abContainerName[256];
1446     DWORD dwBufferLen;
1447     BOOL result, fFound = FALSE;
1448
1449     /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1450      * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1451     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1452     ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1453
1454     /* If the result fits into abContainerName dwBufferLen is left untouched */
1455     dwBufferLen = (DWORD)sizeof(abContainerName);
1456     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1457     ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1458     
1459     /* We only check, if the currently open 'winetest' container is among the enumerated. */
1460     do {
1461         if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1462         dwBufferLen = (DWORD)sizeof(abContainerName);
1463     } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1464         
1465     ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1466 }
1467
1468 static BYTE signBlob[] = {
1469 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1470 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1471 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1472 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1473 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1474 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1475 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1476 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1477 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1478 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1479 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1480 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1481 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1482 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1483 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1484 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1485 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1486 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1487 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1488 0xb6,0x85,0x86,0x07 };
1489
1490 static void test_null_provider(void)
1491 {
1492     HCRYPTPROV prov;
1493     HCRYPTKEY key;
1494     BOOL result;
1495     DWORD keySpec, dataLen,dwParam;
1496     char szName[MAX_PATH];
1497
1498     result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1499     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1500      "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1501     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1502     ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1503      "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1504     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1505      CRYPT_DELETEKEYSET);
1506     ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1507      "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1508     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1509      CRYPT_DELETEKEYSET);
1510     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1511      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1512     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1513     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1514      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1515
1516     /* Delete the default container. */
1517     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1518     /* Once you've deleted the default container you can't open it as if it
1519      * already exists.
1520      */
1521     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1522     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1523      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1524     /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1525     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1526      CRYPT_VERIFYCONTEXT);
1527     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1528     if (!result) return;
1529     dataLen = sizeof(keySpec);
1530     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1531     if (result)
1532         ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1533          "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1534     /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1535      * supported, you can't get the keys from this container.
1536      */
1537     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1538     ok(!result && GetLastError() == NTE_NO_KEY,
1539      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1540     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1541     ok(!result && GetLastError() == NTE_NO_KEY,
1542      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1543     result = CryptReleaseContext(prov, 0);
1544     ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1545     /* You can create a new default container. */
1546     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1547      CRYPT_NEWKEYSET);
1548     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1549     /* But you still can't get the keys (until one's been generated.) */
1550     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1551     ok(!result && GetLastError() == NTE_NO_KEY,
1552      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1553     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1554     ok(!result && GetLastError() == NTE_NO_KEY,
1555      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1556     CryptReleaseContext(prov, 0);
1557     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1558
1559     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1560      CRYPT_DELETEKEYSET);
1561     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1562     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1563      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1564     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1565      CRYPT_VERIFYCONTEXT);
1566     ok(!result && GetLastError() == NTE_BAD_FLAGS,
1567      "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1568     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1569      CRYPT_NEWKEYSET);
1570     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1571     if (!result) return;
1572     /* Test provider parameters getter */
1573     dataLen = sizeof(dwParam);
1574     result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1575     ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1576         "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1577     dataLen = sizeof(dwParam);
1578     result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1579     ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1580         "Expected 0, got 0x%08X\n",dwParam);
1581     dataLen = sizeof(dwParam);
1582     result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1583     ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1584         "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1585     dataLen = sizeof(keySpec);
1586     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1587     ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1588         "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1589     /* PP_CONTAINER parameter */
1590     dataLen = sizeof(szName);
1591     result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1592     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1593         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1594         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1595     /* PP_UNIQUE_CONTAINER parameter */
1596     dataLen = sizeof(szName);
1597     result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1598     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1599         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1600         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1601     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1602     ok(!result && GetLastError() == NTE_NO_KEY,
1603      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1604     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1605     ok(!result && GetLastError() == NTE_NO_KEY,
1606      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1607
1608     /* Importing a key exchange blob.. */
1609     result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1610      0, 0, &key);
1611     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1612     CryptDestroyKey(key);
1613     /* allows access to the key exchange key.. */
1614     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1615     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1616     CryptDestroyKey(key);
1617     /* but not to the private key. */
1618     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1619     ok(!result && GetLastError() == NTE_NO_KEY,
1620      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1621     CryptReleaseContext(prov, 0);
1622     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1623      CRYPT_DELETEKEYSET);
1624
1625     /* Whereas importing a sign blob.. */
1626     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1627      CRYPT_NEWKEYSET);
1628     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1629     if (!result) return;
1630     result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1631     ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1632     /* doesn't allow access to the key exchange key.. */
1633     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1634     ok(!result && GetLastError() == NTE_NO_KEY,
1635      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1636     /* but does to the private key. */
1637     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1638     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1639     CryptDestroyKey(key);
1640
1641     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1642      CRYPT_DELETEKEYSET);
1643
1644
1645     /* test for the bug in accessing the user key in a container
1646      */
1647     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1648      CRYPT_NEWKEYSET);
1649     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1650     result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1651     ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1652     CryptDestroyKey(key);
1653     CryptReleaseContext(prov,0);
1654     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1655     ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1656     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1657     ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1658     CryptDestroyKey(key);
1659
1660     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1661      CRYPT_DELETEKEYSET);
1662
1663     /* test the machine key set */
1664     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1665      CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1666     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1667      CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1668     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1669     CryptReleaseContext(prov, 0);
1670     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1671      CRYPT_MACHINE_KEYSET);
1672     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1673     CryptReleaseContext(prov,0);
1674     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1675        CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1676     ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1677                 GetLastError());
1678     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1679      CRYPT_MACHINE_KEYSET);
1680     ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1681         "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1682
1683 }
1684
1685 START_TEST(rsaenh)
1686 {
1687     if (!init_environment()) 
1688         return;
1689     test_prov();
1690     test_gen_random();
1691     test_hashes();
1692     test_rc4();
1693     test_rc2();
1694     test_des();
1695     test_3des112();
1696     test_3des();
1697     test_hmac();
1698     test_mac();
1699     test_block_cipher_modes();
1700     test_import_private();
1701     test_verify_signature();
1702     test_rsa_encrypt();
1703     test_import_export();
1704     test_enum_container();
1705     clean_up_environment();
1706     test_schannel_provider();
1707     test_null_provider();
1708 }