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