mshtml: Added IHTMLWindow6::get_sessionStorage implementation.
[wine] / dlls / dssenh / tests / dssenh.c
1 /*
2  * Unit tests for dss functions
3  *
4  * Copyright (c) 2012 Marek Kamil Chmiel
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 void test_acquire_context(void)
30 {   /* failure tests common between all four CSP providers */
31
32     HCRYPTPROV hProv = 0;
33     BOOL result;
34
35     /* cannot acquire provider with 0 as Prov Type and NULL as CSP name */
36     SetLastError(0xdeadbeef);
37     result = CryptAcquireContextA(&hProv, NULL, NULL, 0, 0);
38     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
39         "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
40
41     SetLastError(0xdeadbeef);
42     result = CryptAcquireContextA(&hProv, NULL, NULL, 0, CRYPT_VERIFYCONTEXT);
43     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
44         "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
45
46     /* flag allows us to delete a keyset, but not of an unknown provider */
47     SetLastError(0xdeadbeef);
48     result = CryptAcquireContextA(&hProv, NULL, NULL, 0, CRYPT_DELETEKEYSET);
49     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
50         "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
51
52     /* cannot acquire along with PROV_RSA_SIG, not compatible */
53     SetLastError(0xdeadbeef);
54     result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_RSA_SIG, 0);
55     todo_wine
56     ok(!result && GetLastError() == NTE_PROV_TYPE_NO_MATCH,
57         "Expected NTE_PROV_TYPE_NO_MATCH, got %08x\n", GetLastError());
58
59     /* cannot acquire along with MS_DEF_RSA_SIG_PROV, not compatible */
60     SetLastError(0xdeadbeef);
61     result = CryptAcquireContextA(&hProv, NULL, MS_DEF_RSA_SIG_PROV, PROV_DSS, 0);
62     ok(!result && GetLastError() == NTE_KEYSET_NOT_DEF,
63         "Expected NTE_KEYSET_NOT_DEF, got %08x\n", GetLastError());
64
65     /* cannot acquire provider with 0 as Prov Type */
66     SetLastError(0xdeadbeef);
67     result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, 0, 0);
68     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
69         "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
70
71     /* test base DSS provider (PROV_DSS) */
72
73     result = CryptAcquireContextA(
74         &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
75     if(!result)
76     {
77         skip("DSS csp is currently not available, skipping tests.\n");
78         return;
79     }
80     ok(result, "Expected no errors.\n");
81
82     result = CryptReleaseContext(hProv, 0);
83     ok(result, "Expected release of the provider.\n");
84
85     result = CryptAcquireContextA(
86         &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
87     ok(result, "Expected no errors.\n");
88
89     result = CryptReleaseContext(hProv, 0);
90     ok(result, "Expected release of the provider.\n");
91
92     result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS, 0);
93     ok(result, "Expected no errors.\n");
94
95     result = CryptReleaseContext(hProv, 0);
96     ok(result, "Expected release of the provider.\n");
97
98     result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
99     ok(result, "Expected no errors.\n");
100
101     /* test DSS Diffie Hellman provider (PROV_DSS_DH) */
102
103     result = CryptAcquireContextA(
104         &hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
105     ok(result, "Expected no errors.\n");
106
107     result = CryptReleaseContext(hProv, 0);
108     ok(result, "Expected release of the provider.\n");
109
110     result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS_DH, 0);
111     ok(result, "Expected no errors.\n");
112
113     result = CryptReleaseContext(hProv, 0);
114     ok(result, "Expected release of the provider.\n");
115
116     result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, 0);
117     ok(result, "Expected no errors.\n");
118
119     /* test DSS Enhanced provider (MS_ENH_DSS_DH_PROV) */
120
121     SetLastError(0xdeadbeef);
122     result = CryptAcquireContextA(
123         &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
124     if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
125     {
126         win_skip("DSSENH and Schannel provider is broken on WinNT4\n");
127         return;
128     }
129     ok(result, "Expected no errors.\n");
130
131     result = CryptReleaseContext(hProv, 0);
132     ok(result, "Expected release of the provider.\n");
133
134     result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, 0);
135     ok(result, "Expected no errors.\n");
136
137     result = CryptReleaseContext(hProv, 0);
138     ok(result, "Expected release of the provider.\n");
139
140     /* test DSS Schannel provider (PROV_DH_SCHANNEL) */
141
142     result = CryptAcquireContextA(
143         &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, CRYPT_VERIFYCONTEXT);
144     ok(result, "Expected no errors.\n");
145
146     result = CryptReleaseContext(hProv, 0);
147     ok(result, "Expected release of the provider.\n");
148
149     result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DH_SCHANNEL, 0);
150     ok(result, "Expected no errors.\n");
151
152     result = CryptReleaseContext(hProv, 0);
153     ok(result, "Expected release of the provider.\n");
154
155     result = CryptAcquireContextA(
156         &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, 0);
157     ok(result, "Expected no errors.\n");
158
159     result = CryptReleaseContext(hProv, 0);
160     ok(result, "Expected release of the provider.\n");
161
162     /* failure tests, cannot acquire context because the key container already exists */
163     SetLastError(0xdeadbeef);
164     result = CryptAcquireContextA(
165         &hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, CRYPT_NEWKEYSET);
166     ok(!result && GetLastError() == NTE_EXISTS,
167         "Expected NTE_EXISTS, got %08x\n", GetLastError());
168
169     SetLastError(0xdeadbeef);
170     result = CryptAcquireContextA(
171         &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_NEWKEYSET);
172     ok(!result && GetLastError() == NTE_EXISTS,
173         "Expected NTE_EXISTS, got %08x\n", GetLastError());
174
175     SetLastError(0xdeadbeef);
176     result = CryptAcquireContextA(
177         &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, CRYPT_NEWKEYSET);
178     ok(!result && GetLastError() == NTE_EXISTS,
179         "Expected NTE_EXISTS, got %08x\n", GetLastError());
180 }
181
182 struct keylength_test {
183     ALG_ID algid;
184     DWORD flags;
185     BOOL expectedResult;
186     DWORD expectedError;
187     BOOL brokenResult;
188     DWORD brokenError;
189 };
190
191 static const struct keylength_test baseDSS_keylength[] = {
192     /* AT_KEYEXCHANGE is not supported by the base DSS provider */
193     {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
194     {AT_KEYEXCHANGE, 512 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
195     {AT_KEYEXCHANGE, 1024 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
196     {AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS},/* WinNT4 and Win2k */
197     /* min 512 max 1024 increment by 64 */
198     {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
199     {AT_SIGNATURE, 512 << 16, TRUE},
200     {AT_SIGNATURE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
201     {AT_SIGNATURE, 768 << 16, TRUE},
202     {AT_SIGNATURE, 1024 << 16, TRUE},
203     {AT_SIGNATURE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
204     /* CALG_DH_EPHEM is not supported by the base DSS provider */
205     {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
206     {CALG_DH_EPHEM, 512 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
207     {CALG_DH_EPHEM, 1024 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
208     {CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
209     /* CALG_DH_SF is not supported by the base DSS provider */
210     {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
211     {CALG_DH_SF, 512 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
212     {CALG_DH_SF, 1024 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
213     {CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
214     /* min 512 max 1024, increment by 64 */
215     {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
216     {CALG_DSS_SIGN, 512 << 16, TRUE},
217     {CALG_DSS_SIGN, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
218     {CALG_DSS_SIGN, 768 << 16, TRUE},
219     {CALG_DSS_SIGN, 1024 << 16, TRUE},
220     {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
221 };
222
223 static const struct keylength_test dssDH_keylength[] = {
224     /* min 512 max 1024, increment by 64 */
225     {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_FLAGS},
226     {AT_KEYEXCHANGE, 512 << 16, TRUE},
227     {AT_KEYEXCHANGE, 513 << 16, FALSE,  NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
228     {AT_KEYEXCHANGE, 768 << 16, TRUE},
229     {AT_KEYEXCHANGE, 1024 << 16, TRUE},
230     {AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
231     {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
232     {AT_SIGNATURE, 512 << 16, TRUE},
233     {AT_SIGNATURE, 513 << 16, FALSE,  NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
234     {AT_SIGNATURE, 768 << 16, TRUE},
235     {AT_SIGNATURE, 1024 << 16, TRUE},
236     {AT_SIGNATURE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
237     {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_FLAGS},
238     {CALG_DH_EPHEM, 512 << 16, TRUE},
239     {CALG_DH_EPHEM, 513 << 16, FALSE,  NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
240     {CALG_DH_EPHEM, 768 << 16, TRUE},
241     {CALG_DH_EPHEM, 1024 << 16, TRUE},
242     {CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_FLAGS},
243     {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_FLAGS},
244     {CALG_DH_SF, 512 << 16, TRUE},
245     {CALG_DH_SF, 513 << 16, FALSE,  NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
246     {CALG_DH_SF, 768 << 16, TRUE},
247     {CALG_DH_SF, 1024 << 16, TRUE},
248     {CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_FLAGS},
249     {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
250     {CALG_DSS_SIGN, 512 << 16, TRUE},
251     {CALG_DSS_SIGN, 513 << 16, FALSE,  NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
252     {CALG_DSS_SIGN, 768 << 16, TRUE},
253     {CALG_DSS_SIGN, 1024 << 16, TRUE},
254     {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
255 };
256
257 static const struct keylength_test dssENH_keylength[] = {
258     /* min 512 max 1024 (AT_KEYEXCHANGE max 4096), increment by 64*/
259     {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_FLAGS},
260     {AT_KEYEXCHANGE, 512 << 16, TRUE},
261     {AT_KEYEXCHANGE, 513 << 16, FALSE,  NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
262     {AT_KEYEXCHANGE, 768 << 16, TRUE},
263     {AT_KEYEXCHANGE, 1024 << 16, TRUE},
264     {AT_KEYEXCHANGE, 1088 << 16, TRUE},
265     {AT_KEYEXCHANGE, 2048 << 16, TRUE},
266     /* Keylength too large - test bot timeout.
267     {AT_KEYEXCHANGE, 3072 << 16, TRUE},
268     {AT_KEYEXCHANGE, 4096 << 16, TRUE}, */
269     {AT_KEYEXCHANGE, 4160 << 16, FALSE, NTE_BAD_FLAGS},
270     {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
271     {AT_SIGNATURE, 512 << 16, TRUE},
272     {AT_SIGNATURE, 513 << 16, FALSE,  NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
273     {AT_SIGNATURE, 768 << 16, TRUE},
274     {AT_SIGNATURE, 1024 << 16, TRUE},
275     {AT_SIGNATURE, 1032 << 16, FALSE, NTE_BAD_FLAGS},
276     {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_FLAGS},
277     {CALG_DH_EPHEM, 512 << 16, TRUE},
278     {CALG_DH_EPHEM, 513 << 16, FALSE,  NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
279     {CALG_DH_EPHEM, 768 << 16, TRUE},
280     {CALG_DH_EPHEM, 1024 << 16, TRUE},
281     {CALG_DH_EPHEM, 1040 << 16, FALSE, NTE_BAD_FLAGS},
282     {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_FLAGS},
283     {CALG_DH_SF, 512 << 16, TRUE},
284     {CALG_DH_SF, 513 << 16, FALSE,  NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
285     {CALG_DH_SF, 768 << 16, TRUE},
286     {CALG_DH_SF, 1024 << 16, TRUE},
287     {CALG_DH_SF, 1032 << 16, FALSE, NTE_BAD_FLAGS},
288     {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
289     {CALG_DSS_SIGN, 512 << 16, TRUE},
290     {CALG_DSS_SIGN, 513 << 16, FALSE,  NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
291     {CALG_DSS_SIGN, 768 << 16, TRUE},
292     {CALG_DSS_SIGN, 1024 << 16, TRUE},
293     {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
294 };
295
296 static void test_keylength_array(HCRYPTPROV hProv,const struct keylength_test *tests, int testLen)
297 {
298     HCRYPTKEY key;
299     BOOL result;
300     int i;
301
302     for (i = 0; i < testLen; i++)
303     {
304         SetLastError(0xdeadbeef);
305         result = CryptGenKey(hProv, tests[i].algid, tests[i].flags, &key);
306
307         /* success */
308         if(tests[i].expectedResult)
309         {
310             ok(result, "Expected a key, got %08x\n", GetLastError());
311             result = CryptDestroyKey(key);
312             ok(result, "Expected no errors.\n");
313         }
314         else
315         {   /* error but success on older system */
316             if(tests[i].brokenResult)
317                 ok((!result && GetLastError() == tests[i].expectedError) ||
318                     broken(result), "Expected a key, got %x.\n", GetLastError());
319             else
320             {
321                 /* error */
322                 if(!tests[i].brokenError)
323                     ok(!result && GetLastError() == tests[i].expectedError,
324                         "Expected a key, got %x.\n", GetLastError());
325
326                 /* error but different error on older system */
327                 else
328                     ok(!result && (GetLastError() == tests[i].expectedError ||
329                         broken(GetLastError() == tests[i].brokenError)),
330                         "Expected a key, got %x.\n", GetLastError());
331             }
332         }
333     }
334 }
335
336 #define TESTLEN(x) (sizeof(x) / sizeof((x)[0]))
337
338 static void test_keylength(void)
339 {
340     HCRYPTPROV hProv = 0;
341     BOOL result;
342
343     /* acquire base dss provider */
344     result = CryptAcquireContextA(
345         &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
346     if(!result)
347     {
348         skip("DSSENH is currently not available, skipping key length tests.\n");
349         return;
350     }
351     ok(result, "Expected no errors.\n");
352
353     /* perform keylength tests */
354     test_keylength_array(hProv, baseDSS_keylength, TESTLEN(baseDSS_keylength));
355
356     result = CryptReleaseContext(hProv, 0);
357     ok(result, "Expected release of CSP provider.\n");
358
359     /* acquire diffie hellman dss provider */
360     result = CryptAcquireContextA(
361         &hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
362     ok(result, "Expected no errors.\n");
363
364     /* perform keylength tests */
365     test_keylength_array(hProv, dssDH_keylength, TESTLEN(dssDH_keylength));
366
367     result = CryptReleaseContext(hProv, 0);
368     ok(result, "Expected release of CSP provider.\n");
369
370     /* acquire enhanced dss provider */
371     SetLastError(0xdeadbeef);
372     result = CryptAcquireContextA(
373         &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
374     if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
375     {
376         win_skip("DSSENH and Schannel provider is broken on WinNT4\n");
377         return;
378     }
379     ok(result, "Expected no errors.\n");
380
381     /* perform keylength tests */
382     test_keylength_array(hProv, dssENH_keylength, TESTLEN(dssENH_keylength));
383
384     result = CryptReleaseContext(hProv, 0);
385     ok(result, "Expected release of CSP provider.\n");
386
387     /* acquire schannel dss provider */
388     result = CryptAcquireContextA(
389         &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, CRYPT_VERIFYCONTEXT);
390     ok(result, "Expected no errors.\n");
391
392     /* perform keylength tests */
393     test_keylength_array(hProv, dssENH_keylength, TESTLEN(dssENH_keylength));
394
395     result = CryptReleaseContext(hProv, 0);
396     ok(result, "Expected release of CSP provider.\n");
397 }
398
399 struct hash_test {
400     ALG_ID algid;
401     BYTE* input;
402     DWORD dataLen;
403     BYTE hash[20];
404     DWORD hashLen;
405 };
406
407 static const char testHashVal1[] = "I love working with Wine";
408 static const char testHashVal2[] = "Wine is not an emulater.";
409 static const char testHashVal3[] = "";
410
411 static const struct hash_test hash_data[] = {
412     {CALG_MD5, (BYTE *)testHashVal1, sizeof(testHashVal1),
413     {0x4f, 0xf4, 0xd0, 0xdf, 0xe8, 0xf6, 0x6b, 0x1b,
414         0x87, 0xea, 0xca, 0x3d, 0xe8, 0x3c, 0xdd, 0xae}, 16},
415     {CALG_MD5, (BYTE *)testHashVal2, sizeof(testHashVal2),
416     {0x80, 0x5c, 0x1c, 0x0e, 0x79, 0x70, 0xd9, 0x38,
417         0x04, 0x46, 0x19, 0xbe, 0x38, 0x1f, 0xef, 0xe1}, 16},
418     {CALG_MD5, (BYTE *)testHashVal3, sizeof(testHashVal3),
419     {0x93, 0xb8, 0x85, 0xad, 0xfe, 0x0d, 0xa0, 0x89,
420         0xcd, 0xf6, 0x34, 0x90, 0x4f, 0xd5, 0x9f, 0x71}, 16},
421     {CALG_SHA, (BYTE *)testHashVal1, sizeof(testHashVal1),
422     {0x2a, 0xd0, 0xc9, 0x42, 0xfb, 0x73, 0x02, 0x48, 0xbb, 0x5f,
423         0xc2, 0xa4, 0x78, 0xdd, 0xe4, 0x3b, 0xfc, 0x76, 0xe9, 0xe2}, 20},
424     {CALG_SHA, (BYTE *)testHashVal2, sizeof(testHashVal2),
425     {0xfd, 0xfc, 0xab, 0x3a, 0xde, 0x33, 0x01, 0x38, 0xfe, 0xbb,
426         0xc3, 0x13, 0x84, 0x20, 0x9e, 0x55, 0x94, 0x8d, 0xc6, 0x05}, 20},
427     {CALG_SHA, (BYTE *)testHashVal3, sizeof(testHashVal3),
428     {0x5b, 0xa9, 0x3c, 0x9d, 0xb0, 0xcf, 0xf9, 0x3f, 0x52, 0xb5,
429         0x21, 0xd7, 0x42, 0x0e, 0x43, 0xf6, 0xed, 0xa2, 0x78, 0x4f}, 20}
430 };
431
432 static void test_hash(const struct hash_test *tests, int testLen)
433 {
434     HCRYPTPROV hProv = 0;
435     HCRYPTHASH hHash;
436     BYTE hashValue[36];
437     BOOL result;
438     int i;
439
440     result = CryptAcquireContextA(
441         &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
442     if(!result)
443     {
444         skip("DSSENH is currently not available, skipping hashing tests.\n");
445         return;
446     }
447     ok(result, "Expected no errors.\n");
448
449     for(i = 0; i < testLen; i++)
450     {
451         BYTE* data = tests[i].input;
452         DWORD dataLen = tests[i].dataLen;
453         DWORD hashLen;
454
455         /* test algid hash */
456         result = CryptCreateHash(hProv, tests[i].algid, 0, 0, &hHash);
457         ok(result, "Expected creation of a hash.\n");
458
459         result = CryptHashData(hHash, data, dataLen, 0);
460         ok(result, "Expected data to be added to hash.\n");
461
462         dataLen = sizeof(DWORD);
463         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashLen, &dataLen, 0);
464         ok(result && (hashLen == tests[i].hashLen), "Expected %d hash len, got %d.Error: %x\n",
465             tests[i].hashLen, hashLen, GetLastError());
466
467         result = CryptGetHashParam(hHash, HP_HASHVAL, hashValue, &hashLen, 0);
468         ok(result, "Expected hash value return.\n");
469
470         ok(!memcmp(hashValue, tests[i].hash, tests[i].hashLen), "Incorrect hash output.\n");
471
472         result = CryptHashData(hHash, data, dataLen, 0);
473         ok(!result, "Should not be able to add to hash.\n");
474
475         result = CryptDestroyHash(hHash);
476         ok(result, "Expected destruction of hash.\n");
477     }
478     result = CryptReleaseContext(hProv, 0);
479     ok(result, "Expected release of the DSS Enhanced provider.\n");
480 }
481
482 struct encrypt_test {
483     ALG_ID algid;
484     DWORD keyLength;
485     const char *plain;
486     DWORD plainLen;
487     const BYTE *decrypted;
488     const BYTE *encrypted;
489 };
490
491 static const char dataToEncrypt1[] = "Great performance with Wine.";
492 static const char dataToEncrypt2[] = "Wine implements Windows API";
493 static const char dataToEncrypt3[] = "";
494
495 static const BYTE encrypted3DES_1[] = {
496 0x6c,0x60,0x19,0x41,0x27,0xc1,0x16,0x69, 0x6f,0x96,0x0c,0x2e,0xa4,0x5f,0xf5,0x6a,
497 0xed,0x4b,0xec,0xd4,0x92,0x0c,0xe2,0x34, 0xe1,0x4a,0xb5,0xe2,0x05,0x43,0xfe,0x17
498 };
499 static const BYTE encrypted3DES_2[] = {
500 0x17,0xeb,0x80,0xde,0xac,0x4d,0x9e,0xd0, 0xa9,0xae,0x74,0xb5,0x86,0x1a,0xea,0xb4,
501 0x96,0x27,0x5d,0x75,0x4f,0xdd,0x87,0x60, 0xfc,0xaf,0xa1,0x82,0x83,0x09,0xf1,0xca
502 };
503 static const BYTE encrypted3DES_3[] = {0xaf, 0x36, 0xc0, 0x3d, 0x78, 0x64, 0xc4, 0x4a};
504
505 static const BYTE encrypted3DES112_1[] = {
506 0xb3,0xf8,0x4b,0x08,0xd6,0x23,0xcb,0xca, 0x43,0x26,0xd9,0x9f,0x6b,0x99,0x09,0xe9,
507 0x8c,0x4c,0x7d,0xef,0x49,0xda,0x0b,0x44, 0xcc,0x8d,0x06,0x6b,0xed,0xb7,0xf1,0x67
508 };
509 static const BYTE encrypted3DES112_2[] = {
510 0xdc,0xcf,0x93,0x11,0x7a,0xe4,0xcd,0x3f, 0x11,0xd8,0xe0,0x1e,0xe0,0x8d,0x9c,0xba,
511 0x97,0x5d,0x74,0x4d,0x83,0x03,0x5c,0xf2, 0x01,0xaf,0xed,0x7a,0x87,0x8f,0x88,0x8b
512 };
513 static const BYTE encrypted3DES112_3[] = {0x04, 0xb3, 0x9c, 0x59, 0x48, 0xc7, 0x2f, 0xd1};
514
515 static const BYTE encryptedDES_1[] = {
516 0x3d,0xdc,0x54,0xaf,0x66,0x72,0x4e,0xef, 0x9d,0x35,0x02,0xc2,0x1a,0xf4,0x1f,0x01,
517 0xb1,0xaf,0x13,0xd9,0xbe,0x7b,0xd4,0xf3, 0xf5,0x9d,0x2a,0xd8,0x32,0x90,0xe9,0x0b
518 };
519 static const BYTE encryptedDES_2[] = {
520 0xa8,0x05,0xd7,0xe9,0x61,0xf4,0x6c,0xce, 0x95,0x2b,0x52,0x08,0x25,0x03,0x30,0xac,
521 0xd7,0xe7,0xd3,0x07,0xb2,0x68,0x63,0x7b, 0xe3,0xab,0x26,0x1e,0x5c,0xec,0x42,0x4f
522 };
523 static const BYTE encryptedDES_3[] = {0x35, 0x02, 0xbb, 0x7c, 0x43, 0x5b, 0xf5, 0x59};
524
525 static const BYTE encryptedRC2_1[] = {
526 0x9e,0xcb,0xa2,0x27,0xc2,0xec,0x10,0xe0, 0x94,0xb3,0xc3,0x9d,0x7d,0xe2,0x12,0xe4,
527 0xb0,0xde,0xd9,0x46,0xca,0x1f,0xa6,0xfa, 0xa4,0x79,0x08,0x59,0xa6,0x00,0x62,0x16
528 };
529 static const BYTE encryptedRC2_2[] = {
530 0x29,0x06,0xfd,0xa1,0xe0,0x88,0x89,0xb0, 0x4d,0x7f,0x96,0x9d,0x2c,0x44,0xa1,0xd2,
531 0xbe,0xc6,0xaf,0x10,0xb8,0x86,0x68,0x1b, 0x1d,0x9f,0x3c,0xc4,0x12,0x02,0xbc,0x73
532 };
533 static const BYTE encryptedRC2_3[] = {0x26,0x40,0x73,0xfe,0x13,0xbb,0x32,0xa8};
534
535 static const BYTE encryptedRC4_1[] = {
536 0x5a,0x48,0xeb,0x16,0x96,0x23,0x16,0xb7, 0xbb,0x36,0xe8,0x43,0x88,0x74,0xb1,0x9d,
537 0x96,0xf0,0x84,0x0f,0x5a,0x56,0xf9,0x62, 0xae,0xb5,0x4a,0xce,0x52
538 };
539 static const BYTE encryptedRC4_2[] = {
540 0x4a,0x53,0xe0,0x12,0xc2,0x6a,0x0b,0xa2, 0xa5,0x35,0xea,0x54,0x8b,0x61,0xac,0xde,
541 0xa4,0xb9,0x9d,0x02,0x41,0x49,0xaa,0x15, 0x86,0x8b,0x66,0xe0
542 };
543 static const BYTE encryptedRC4_3[] = {0x1d};
544
545 static const struct encrypt_test encrypt_data[] = {
546     {CALG_3DES, 168 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
547         encrypted3DES_1},
548     {CALG_3DES, 168 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
549         encrypted3DES_2},
550     {CALG_3DES, 168 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
551         encrypted3DES_3},
552     {CALG_3DES_112, 112 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
553         encrypted3DES112_1},
554     {CALG_3DES_112, 112 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
555         encrypted3DES112_2},
556     {CALG_3DES_112, 112 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
557         encrypted3DES112_3},
558     {CALG_DES, 56 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
559         encryptedDES_1},
560     {CALG_DES, 56 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
561         encryptedDES_2},
562     {CALG_DES, 56 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
563         encryptedDES_3},
564     /* CALG_RC2 key unexpected results under Win2K when default key length is used, here we use
565        minimum length because Win2K's DSSENH provider has a differnt default key length compared
566        to the younger operating systems, though there is no default key len issue with CALG_RC4 */
567     {CALG_RC2, 40 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
568         encryptedRC2_1},
569     {CALG_RC2, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
570         encryptedRC2_2},
571     {CALG_RC2, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
572         encryptedRC2_3},
573     {CALG_RC4, 40 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
574         encryptedRC4_1},
575     {CALG_RC4, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
576         encryptedRC4_2},
577     {CALG_RC4, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
578         encryptedRC4_3}
579 };
580
581 static void test_data_encryption(const struct encrypt_test *tests, int testLen)
582 {   /* Here we test the same encryption ciphers as the RSAENH cryptographic service provider */
583     HCRYPTPROV hProv = 0;
584     HCRYPTKEY pKey = 0;
585     HCRYPTHASH hHash;
586     const char dataToHash[] = "I love working with Wine";
587     unsigned char pbData[36];
588     DWORD dataLen;
589     BOOL result;
590     int i;
591
592     /* acquire dss enhanced provider */
593     SetLastError(0xdeadbeef);
594     result = CryptAcquireContextA(
595         &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
596     if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
597     {
598         skip("DSSENH is currently not available, skipping encryption tests.\n");
599         return;
600     }
601     ok(result, "Expected no errors.\n");
602
603     /* testing various encryption algorithms */
604     for(i = 0; i < testLen; i++)
605     {
606         memcpy(pbData, tests[i].plain, tests[i].plainLen);
607         dataLen = tests[i].plainLen;
608
609         SetLastError(0xdeadbeef);
610         result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
611         ok(result, "Expected creation of a MD5 hash for key derivation.\n");
612
613         result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
614         ok(result, "Expected data to be added to hash for key derivation.\n");
615
616         /* Derive key */
617         result = CryptDeriveKey(hProv, tests[i].algid, hHash, tests[i].keyLength, &pKey);
618         ok(result, "Expected a derived key.\n");
619
620         result = CryptDestroyHash(hHash);
621         ok(result, "Expected destruction of hash after deriving key.\n");
622
623         /* testing CryptEncrypt with ALGID from array */
624         result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
625         ok(result, "Expected data encryption.\n");
626
627         /* Verify we have received expected encrypted data */
628         ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
629
630         result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
631         ok(result, "Expected data decryption.\n");
632
633         /* Verify we have received expected decrypted data */
634         ok(!memcmp(pbData, tests[i].decrypted, dataLen), "Incorrect decrypted data.\n");
635
636         result = CryptDestroyKey(pKey);
637         ok(result, "Expected no DestroyKey errors.\n");
638     }
639     result = CryptReleaseContext(hProv, 0);
640     ok(result, "Expected release of the provider\n");
641 }
642
643 struct ciphermode_test {
644     DWORD cipherMode;
645     BOOL expectedResult;
646     DWORD expectedError;
647     const BYTE *encrypted;
648 };
649
650 static const BYTE encryptedCFB[] = {
651 0x51,0x15,0x77,0xab,0x62,0x1f,0x7d,0xcb, 0x35,0x1e,0xd8,0xd3,0x2a,0x00,0xf0,0x94,
652 0x7c,0xa5,0x28,0xda,0xb8,0x81,0x15,0x99, 0xd1,0xd5,0x06,0x1d,0xd3,0x46,0x7e,0xca
653 };
654 static const BYTE encryptedCBC[] = {
655 0x8f,0x7b,0x56,0xeb,0xad,0x4d,0x76,0xc2, 0xd5,0x1d,0xf0,0x60,0x9d,0xde,0x96,0xe8,
656 0xb7,0x7b,0xeb,0x4b,0xee,0x3f,0xae,0x05, 0x20,0xf5,0xe0,0x75,0xa0,0x1d,0xf9,0x39
657 };
658 static const BYTE encryptedECB[] = {
659 0x8f,0x7b,0x56,0xeb,0xad,0x4d,0x76,0xc2, 0x8b,0xe0,0x4e,0xe4,0x98,0x4f,0xb8,0x3b,
660 0xf3,0xeb,0x6f,0x0a,0x57,0x91,0xdd,0xc7, 0x34,0x5d,0x4c,0xa3,0x7e,0x97,0xbf,0xee
661 };
662
663 static const struct ciphermode_test ciphermode_data[] = {
664     {CRYPT_MODE_CFB, TRUE, 0xdeadbeef, encryptedCFB}, /* Testing cipher block chaining */
665     {CRYPT_MODE_CBC, TRUE, 0xdeadbeef, encryptedCBC}, /* Testing cipher feedback */
666     {CRYPT_MODE_ECB, TRUE, 0xdeadbeef, encryptedECB}, /* Testing electronic codebook */
667     {CRYPT_MODE_OFB, FALSE, NTE_BAD_DATA}/* DSSENH does not support Output Feedback cipher mode */
668 };
669
670 static void test_cipher_modes(const struct ciphermode_test *tests, int testLen)
671 {
672     HCRYPTPROV hProv = 0;
673     HCRYPTKEY pKey = 0;
674     HCRYPTHASH hHash;
675     const char plainText[] = "Testing block cipher modes.";
676     const char dataToHash[] = "GSOC is awesome!";
677     unsigned char pbData[36];
678     int plainLen = sizeof(plainText), i;
679     DWORD mode, dataLen;
680     BOOL result;
681
682     /* acquire dss enhanced provider */
683     SetLastError(0xdeadbeef);
684     result = CryptAcquireContextA(
685         &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
686     if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
687     {
688         skip("DSSENH is currently not available, skipping block cipher mode tests.\n");
689         return;
690     }
691     ok(result, "Expected no errors.\n");
692
693     SetLastError(0xdeadbeef);
694     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
695     ok(result, "Expected creation of a MD5 hash for key derivation.\n");
696
697     result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
698     ok(result, "Expected data to be added to hash for key derivation.\n");
699
700     /* Derive a CALG_RC2 key, but could be any other encryption cipher */
701     result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &pKey);
702     ok(result, "Expected a derived key.\n");
703
704     result = CryptDestroyHash(hHash);
705     ok(result, "Expected destruction of hash after deriving key.\n");
706
707     /* test block cipher modes */
708     for(i = 0; i < testLen; i++)
709     {
710         SetLastError(0xdeadbeef);
711         dataLen = plainLen;
712         mode = tests[i].cipherMode;
713         memcpy(pbData, plainText, plainLen);
714
715         result = CryptSetKeyParam(pKey, KP_MODE, (BYTE*)&mode, 0);
716         if(tests[i].expectedResult)
717         {
718             ok(result, "Expected setting of KP_MODE, got %x.\n", GetLastError());
719
720             result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
721             ok(result, "Expected data encryption, got %x.\n", GetLastError());
722
723             /* Verify we have the correct encrypted data */
724             ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
725
726             result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
727             ok(result, "Expected data decryption, got %x.\n", GetLastError());
728
729             /* Verify we have the correct decrypted data */
730             ok(!memcmp(pbData, (BYTE *)plainText, dataLen), "Incorrect decrypted data.\n");
731         }
732         else
733         {   /* Expected error */
734             ok(!result && GetLastError() == tests[i].expectedError, "Expected %d, got %x.\n",
735                 tests[i].expectedError, GetLastError());
736         }
737     }
738     result = CryptDestroyKey(pKey);
739     ok(result, "Expected no DestroyKey errors.\n");
740
741     result = CryptReleaseContext(hProv, 0);
742     ok(result, "Expected release of the provider.\n");
743 }
744
745 struct signature_test {
746     const BYTE *privateKey;
747     DWORD keyLen;
748     BYTE* signData;
749     DWORD dataLen;
750 };
751
752 static const char dataToSign1[] = "Put your hands up for Cryptography :)";
753 static const char dataToSign2[] = "With DSSENH implemented, applications requiring it will now work.";
754 static const char dataToSign3[] = "";
755
756 static const BYTE AT_SIGNATURE_PrivateKey[] = {
757 0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00, 0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,
758 0x01,0xd1,0xfc,0x7a,0x70,0x53,0xb2,0x48, 0x70,0x23,0x19,0x1f,0x3c,0xe1,0x26,0x14,
759 0x7e,0x9f,0x0f,0x7f,0x33,0x5e,0x2b,0xf7, 0xca,0x01,0x74,0x8c,0xb4,0xfd,0xf6,0x44,
760 0x95,0x35,0x56,0xaa,0x4d,0x62,0x48,0xe2, 0xd1,0xa2,0x7e,0x6e,0xeb,0xd6,0xcc,0x7c,
761 0xe8,0xfd,0x21,0x9a,0xa2,0xfd,0x7a,0x9d, 0x1a,0x38,0x69,0x87,0x39,0x5a,0x91,0xc0,
762 0x52,0x2b,0x9f,0x2a,0x54,0x78,0x37,0x82, 0x9a,0x70,0x57,0xab,0xec,0x93,0x8e,0xac,
763 0x73,0x04,0xe8,0x53,0x72,0x72,0x32,0xc6, 0xcb,0xef,0x47,0x98,0x3c,0x56,0x49,0x62,
764 0xcb,0xbb,0xe7,0x34,0x84,0xa6,0x72,0x3a, 0xbe,0x26,0x46,0x86,0xca,0xcb,0x35,0x62,
765 0x4f,0x19,0x18,0x0b,0xb0,0x78,0xae,0xd5, 0x42,0xdf,0x26,0xdb,0x85,0x63,0x77,0x85,
766 0x01,0x3b,0x32,0xbe,0x5c,0xf8,0x05,0xc8, 0xde,0x17,0x7f,0xb9,0x03,0x82,0xfa,0xf1,
767 0x9e,0x32,0x73,0xfa,0x8d,0xea,0xa3,0x30, 0x48,0xe2,0xdf,0x5a,0xcb,0x83,0x3d,0xff,
768 0x56,0xe9,0xc0,0x94,0xf8,0x6d,0xb3,0xaf, 0x4a,0x97,0xb9,0x43,0x0e,0xd4,0x28,0x98,
769 0x57,0x2e,0x3a,0xca,0xde,0x6f,0x45,0x0d, 0xfb,0x58,0xec,0x78,0x34,0x2e,0x46,0x4d,
770 0xfe,0x98,0x02,0xbb,0xef,0x07,0x1a,0x13, 0xb6,0xc2,0x2c,0x06,0xd9,0x0c,0xc4,0xb0,
771 0x4c,0x3a,0xfc,0x01,0x63,0xb5,0x5a,0x5d, 0x2d,0x9c,0x47,0x04,0x67,0x51,0xf2,0x52,
772 0xf5,0x82,0x36,0xeb,0x6e,0x66,0x58,0x4c, 0x10,0x2c,0x29,0x72,0x4a,0x6f,0x6b,0x6c,
773 0xe0,0x93,0x31,0x42,0xf6,0xda,0xfa,0x5b, 0x22,0x43,0x9b,0x1a,0x98,0x71,0xe7,0x41,
774 0x74,0xe9,0x12,0xa4,0x1f,0x27,0x0a,0x63, 0x94,0x49,0xd7,0xad,0xa5,0xc4,0x5c,0xc3,
775 0xc9,0x70,0xb3,0x7b,0x16,0xb6,0x1d,0xd4, 0x09,0xc4,0x9a,0x46,0x2d,0x0e,0x75,0x07,
776 0x31,0x7b,0xed,0x45,0xcd,0x99,0x84,0x14, 0xf1,0x01,0x00,0x00,0x93,0xd5,0xa3,0xe4,
777 0x34,0x05,0xeb,0x98,0x3b,0x5f,0x2f,0x11, 0xa4,0xa5,0xc4,0xff,0xfb,0x22,0x7c,0x54
778 };
779
780 static const BYTE DSS_SIGN_PrivateKey[] = {
781 0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00, 0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,
782 0xf7,0x9e,0x89,0xa2,0xcd,0x0b,0x61,0xe0, 0xa3,0xe5,0x86,0x6b,0x04,0x98,0x80,0x9c,
783 0x36,0xc2,0x76,0x4e,0x22,0xd5,0x21,0xaa, 0x03,0x59,0xf4,0x95,0xb2,0x11,0x1f,0xa0,
784 0xc5,0xfc,0xbe,0x5d,0x1f,0x2e,0xf4,0x36, 0x40,0x48,0x81,0x51,0xb4,0x25,0x86,0xe0,
785 0x98,0xc8,0x4d,0xa0,0x08,0x99,0xa1,0x00, 0x45,0x1b,0x75,0x6b,0x0d,0x3e,0x7d,0x13,
786 0xd7,0x23,0x32,0x08,0xf4,0xeb,0x27,0x9e, 0xe9,0x05,0x5d,0xac,0xc8,0xd7,0x62,0x13,
787 0x43,0x2a,0x69,0x65,0xdc,0xe6,0x52,0xf9, 0x6a,0xe8,0x07,0xcf,0x3e,0xf8,0xc9,0x1d,
788 0x8e,0xdf,0x4e,0x9a,0xd1,0x48,0xf2,0xda, 0x9e,0xfa,0x92,0x5f,0x6d,0x57,0xf2,0xa4,
789 0x5f,0x60,0xce,0x92,0x7a,0x80,0x39,0x21, 0x9d,0x4d,0x3a,0x60,0x76,0x4c,0x2f,0xc0,
790 0xd3,0xf4,0x14,0x03,0x03,0x05,0xa9,0x0c, 0x57,0x72,0x4f,0x60,0x3c,0xe9,0x09,0x54,
791 0x0c,0x2a,0x56,0xda,0x30,0xb6,0x2e,0x6a, 0x96,0x7f,0x4a,0x8f,0x83,0x0a,0xb9,0x5c,
792 0xff,0x84,0xfa,0x0e,0x85,0x81,0x46,0xe9, 0x1c,0xbb,0x78,0x1d,0x78,0x25,0x00,0x8c,
793 0x78,0x56,0x68,0xe4,0x06,0x37,0xcc,0xc7, 0x22,0x27,0xee,0x0e,0xf8,0xca,0xfc,0x72,
794 0x0e,0xd6,0xe6,0x90,0x30,0x66,0x22,0xe2, 0xa2,0xbf,0x2e,0x35,0xbc,0xe7,0xd6,0x24,
795 0x6a,0x3d,0x06,0xe8,0xe2,0xbe,0x96,0xcc, 0x9a,0x08,0x06,0xb5,0x44,0x83,0xb0,0x7b,
796 0x70,0x7b,0x2d,0xc3,0x46,0x9a,0xc5,0x6b, 0xd9,0xde,0x9a,0x24,0xc9,0xea,0xf5,0x28,
797 0x69,0x8a,0x17,0xca,0xdf,0xc4,0x0e,0xa3, 0x08,0x22,0x99,0xd2,0x27,0xdc,0x9b,0x08,
798 0x54,0x4a,0xf9,0xb1,0x74,0x3a,0x9d,0xd9, 0xc2,0x82,0x21,0xf5,0x97,0x04,0x90,0x37,
799 0xda,0xd9,0xdc,0x19,0xad,0x83,0xcd,0x35, 0xb0,0x4e,0x06,0x68,0xd1,0x69,0x7e,0x73,
800 0x93,0xbe,0xa5,0x05,0xb3,0xcc,0xd2,0x51, 0x3c,0x00,0x00,0x00,0x16,0xe1,0xac,0x17,
801 0xdc,0x68,0xae,0x03,0xad,0xf7,0xb9,0xca, 0x0d,0xca,0x27,0xef,0x76,0xda,0xe5,0xcb
802 };
803
804 static const struct signature_test dssSign_data[] = {
805     {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign1, sizeof(dataToSign1)},
806     {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign2, sizeof(dataToSign2)},
807     {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign3, sizeof(dataToSign3)},
808     {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign1, sizeof(dataToSign1)},
809     {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign2, sizeof(dataToSign2)},
810     {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign3, sizeof(dataToSign3)}
811 };
812
813 static void test_signhash_array(HCRYPTPROV hProv, const struct signature_test *tests, int testLen)
814 {
815     HCRYPTHASH hHash1, hHash2;
816     HCRYPTKEY privKey = 0, pubKey = 0;
817     BYTE pubKeyBuffer[512];
818     BYTE signValue1[40], signValue2[40];
819     BYTE hashValue1[40], hashValue2[40];
820     DWORD hashLen1, hashLen2, pubKeyLen;
821     DWORD dataLen1, dataLen2;
822     BOOL result;
823     int i;
824
825     for (i = 0; i < testLen; i++)
826     {
827         DWORD signLen1 = tests[i].dataLen;
828         DWORD signLen2 = tests[i].dataLen;
829
830         /* Get a private key of array specified ALG_ID */
831         result = CryptImportKey(hProv, tests[i].privateKey, tests[i].keyLen, 0, 0, &privKey);
832         ok(result, "Failed to imported key, got %x\n", GetLastError());
833
834         /* Create hash object and add data for signature 1 */
835         result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
836         ok(result, "Failed to create a hash, got %x\n", GetLastError());
837
838         result = CryptHashData(hHash1, tests[i].signData, signLen1, 0);
839         ok(result, "Failed to add data to hash, got %x\n", GetLastError());
840
841         /* Create hash object and add data for signature 2 */
842         result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
843         ok(result, "Failed to create a hash, got %x\n", GetLastError());
844
845         result = CryptHashData(hHash2, tests[i].signData, signLen2, 0);
846         ok(result, "Failed to add data to hash, got %x\n", GetLastError());
847
848         /* Acquire hash length and hash value */
849         dataLen1 = sizeof(DWORD);
850         result = CryptGetHashParam(hHash1, HP_HASHSIZE, (BYTE *)&hashLen1, &dataLen1, 0);
851         ok(result, "Failed to get hash length, got %x\n", GetLastError());
852
853         result = CryptGetHashParam(hHash1, HP_HASHVAL, hashValue1, &hashLen1, 0);
854         ok(result, "Failed to return hash value.\n");
855
856         dataLen2 = sizeof(DWORD);
857         result = CryptGetHashParam(hHash2, HP_HASHSIZE, (BYTE *)&hashLen2, &dataLen2, 0);
858         ok(result, "Failed to get hash length, got %x\n", GetLastError());
859
860         result = CryptGetHashParam(hHash2, HP_HASHVAL, hashValue2, &hashLen2, 0);
861         ok(result, "Failed to return hash value.\n");
862
863         /* Compare hashes to ensure they are the same */
864         ok(hashLen1 ==  hashLen2, "Hash lengths were not the same.");
865         ok(!memcmp(hashValue1, hashValue2, hashLen2), "Hashes were not identical.\n");
866
867         /* Sign hash 1 */
868         result = CryptSignHash(hHash1, AT_SIGNATURE, NULL, 0, NULL, &signLen1);
869         ok(result, "Failed to get signature length, got %x\n", GetLastError());
870         ok(signLen1 == 40, "Expected a 40-byte signature, got %d\n", signLen1);
871
872         result = CryptSignHash(hHash1, AT_SIGNATURE, NULL, 0, signValue1, &signLen1);
873         ok(result, "Failed to sign hash, got %x\n", GetLastError());
874
875         /* Sign hash 2 */
876         result = CryptSignHash(hHash2, AT_SIGNATURE, NULL, 0, NULL, &signLen2);
877         ok(result, "Failed to get signature length, got %x\n", GetLastError());
878         ok(signLen2 == 40, "Expected a 40-byte signature, got %d\n", signLen2);
879
880         result = CryptSignHash(hHash2, AT_SIGNATURE, NULL, 0, signValue2, &signLen2);
881         ok(result, "Failed to sign hash2, got %x\n", GetLastError());
882
883         /* Compare signatures to ensure they are both different, because every DSS signature
884            should be different even if the input hash data is identical */
885         ok(memcmp(signValue1, signValue2, signLen2), "Expected two different signatures from "
886             "the same hash input.");
887
888         result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen);
889         ok(result, "Failed to acquire public key length, got %x\n", GetLastError());
890
891         /* Export the public key */
892         result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, pubKeyBuffer, &pubKeyLen);
893         ok(result, "Failed to export public key, got %x\n", GetLastError());
894
895         result = CryptDestroyHash(hHash1);
896         ok(result, "Failed to destroy hash1, got %x\n", GetLastError());
897         result = CryptDestroyHash(hHash2);
898         ok(result, "Failed to destroy hash2, got %x\n", GetLastError());
899
900         /* Destroy the private key */
901         result = CryptDestroyKey(privKey);
902         ok(result, "Failed to destroy private key, got %x\n", GetLastError());
903
904         /* Import the public key we obtained earlier */
905         result = CryptImportKey(hProv, pubKeyBuffer, pubKeyLen, 0, 0, &pubKey);
906         ok(result, "Failed to import public key, got %x\n", GetLastError());
907
908         result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
909         ok(result, "Failed to create hash, got %x\n", GetLastError());
910
911         /* Hash the data to compare with the signed hash */
912         result = CryptHashData(hHash1, tests[i].signData, tests[i].dataLen, 0);
913         ok(result, "Failed to add data to hash1, got %x\n", GetLastError());
914
915         /* Verify signed hash 1 */
916         result = CryptVerifySignature(hHash1, signValue1, sizeof(signValue1), pubKey, NULL, 0);
917         ok(result, "Failed to verify signature, got %x\n", GetLastError());
918
919         result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
920         ok(result, "Failed to create hash, got %x\n", GetLastError());
921
922         /* Hash the data to compare with the signed hash */
923         result = CryptHashData(hHash2, tests[i].signData, tests[i].dataLen, 0);
924         ok(result, "Failed to add data to hash2, got %x\n", GetLastError());
925
926         /* Verify signed hash 2 */
927         result = CryptVerifySignature(hHash2, signValue2, sizeof(signValue2), pubKey, NULL, 0);
928         ok(result, "Failed to verify signature, got %x\n", GetLastError());
929
930         result = CryptDestroyHash(hHash1);
931         ok(result, "Failed to destroy hash1, got %x\n", GetLastError());
932         result = CryptDestroyHash(hHash2);
933         ok(result, "Failed to destroy hash2, got %x\n", GetLastError());
934
935         /* Destroy the public key */
936         result = CryptDestroyKey(pubKey);
937         ok(result, "Failed to destroy public key, got %x\n", GetLastError());
938     }
939 }
940
941 static void test_verify_signature(void)
942 {
943     HCRYPTPROV hProv = 0;
944     BOOL result;
945
946     /* acquire base dss provider */
947     result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
948     if(!result)
949     {
950         skip("DSSENH is currently not available, skipping signature verification tests.\n");
951         return;
952     }
953     ok(result, "Failed to acquire CSP.\n");
954
955     test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
956
957     result = CryptReleaseContext(hProv, 0);
958     ok(result, "Failed to release CSP provider.\n");
959
960     /* acquire diffie hellman dss provider */
961     result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, 0);
962     ok(result, "Failed to acquire CSP.\n");
963
964     test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
965
966     result = CryptReleaseContext(hProv, 0);
967     ok(result, "Failed to release CSP provider.\n");
968
969     /* acquire enhanced dss provider */
970     SetLastError(0xdeadbeef);
971     result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, 0);
972     if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
973     {
974         win_skip("DSSENH and Schannel provider is broken on WinNT4, skipping signature "
975             "verification tests.\n");
976         return;
977     }
978     ok(result, "Failed to acquire CSP.\n");
979
980     test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
981
982     result = CryptReleaseContext(hProv, 0);
983     ok(result, "Failed to release CSP provider.\n");
984
985     /* acquire schannel dss provider */
986     result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, 0);
987     ok(result, "Failed to acquire CSP.\n");
988
989     test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
990
991     result = CryptReleaseContext(hProv, 0);
992     ok(result, "Failed to release CSP provider.\n");
993 }
994
995 START_TEST(dssenh)
996 {
997     test_acquire_context();
998     test_keylength();
999     test_hash(hash_data, TESTLEN(hash_data));
1000     test_data_encryption(encrypt_data, TESTLEN(encrypt_data));
1001     test_cipher_modes(ciphermode_data, TESTLEN(ciphermode_data));
1002     test_verify_signature();
1003 }