2 * Unit tests for dss functions
4 * Copyright (c) 2012 Marek Kamil Chmiel
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.
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.
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
23 #include "wine/test.h"
29 static void test_acquire_context(void)
30 { /* failure tests common between all four CSP providers */
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());
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());
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());
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);
56 ok(!result && GetLastError() == NTE_PROV_TYPE_NO_MATCH,
57 "Expected NTE_PROV_TYPE_NO_MATCH, got %08x\n", GetLastError());
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());
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());
71 /* test base DSS provider (PROV_DSS) */
73 result = CryptAcquireContextA(
74 &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
77 skip("DSS csp is currently not available, skipping tests.\n");
80 ok(result, "Expected no errors.\n");
82 result = CryptReleaseContext(hProv, 0);
83 ok(result, "Expected release of the provider.\n");
85 result = CryptAcquireContextA(
86 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
87 ok(result, "Expected no errors.\n");
89 result = CryptReleaseContext(hProv, 0);
90 ok(result, "Expected release of the provider.\n");
92 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS, 0);
93 ok(result, "Expected no errors.\n");
95 result = CryptReleaseContext(hProv, 0);
96 ok(result, "Expected release of the provider.\n");
98 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
99 ok(result, "Expected no errors.\n");
101 /* test DSS Diffie Hellman provider (PROV_DSS_DH) */
103 result = CryptAcquireContextA(
104 &hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
105 ok(result, "Expected no errors.\n");
107 result = CryptReleaseContext(hProv, 0);
108 ok(result, "Expected release of the provider.\n");
110 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS_DH, 0);
111 ok(result, "Expected no errors.\n");
113 result = CryptReleaseContext(hProv, 0);
114 ok(result, "Expected release of the provider.\n");
116 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, 0);
117 ok(result, "Expected no errors.\n");
119 /* test DSS Enhanced provider (MS_ENH_DSS_DH_PROV) */
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)
126 win_skip("DSSENH and Schannel provider is broken on WinNT4\n");
129 ok(result, "Expected no errors.\n");
131 result = CryptReleaseContext(hProv, 0);
132 ok(result, "Expected release of the provider.\n");
134 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, 0);
135 ok(result, "Expected no errors.\n");
137 result = CryptReleaseContext(hProv, 0);
138 ok(result, "Expected release of the provider.\n");
140 /* test DSS Schannel provider (PROV_DH_SCHANNEL) */
142 result = CryptAcquireContextA(
143 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, CRYPT_VERIFYCONTEXT);
144 ok(result, "Expected no errors.\n");
146 result = CryptReleaseContext(hProv, 0);
147 ok(result, "Expected release of the provider.\n");
149 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DH_SCHANNEL, 0);
150 ok(result, "Expected no errors.\n");
152 result = CryptReleaseContext(hProv, 0);
153 ok(result, "Expected release of the provider.\n");
155 result = CryptAcquireContextA(
156 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, 0);
157 ok(result, "Expected no errors.\n");
159 result = CryptReleaseContext(hProv, 0);
160 ok(result, "Expected release of the provider.\n");
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());
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());
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());
182 struct keylength_test {
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}
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}
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}
296 static void test_keylength_array(HCRYPTPROV hProv,const struct keylength_test *tests, int testLen)
302 for (i = 0; i < testLen; i++)
304 SetLastError(0xdeadbeef);
305 result = CryptGenKey(hProv, tests[i].algid, tests[i].flags, &key);
308 if(tests[i].expectedResult)
310 ok(result, "Expected a key, got %08x\n", GetLastError());
311 result = CryptDestroyKey(key);
312 ok(result, "Expected no errors.\n");
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());
322 if(!tests[i].brokenError)
323 ok(!result && GetLastError() == tests[i].expectedError,
324 "Expected a key, got %x.\n", GetLastError());
326 /* error but different error on older system */
328 ok(!result && (GetLastError() == tests[i].expectedError ||
329 broken(GetLastError() == tests[i].brokenError)),
330 "Expected a key, got %x.\n", GetLastError());
336 #define TESTLEN(x) (sizeof(x) / sizeof((x)[0]))
338 static void test_keylength(void)
340 HCRYPTPROV hProv = 0;
343 /* acquire base dss provider */
344 result = CryptAcquireContextA(
345 &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
348 skip("DSSENH is currently not available, skipping key length tests.\n");
351 ok(result, "Expected no errors.\n");
353 /* perform keylength tests */
354 test_keylength_array(hProv, baseDSS_keylength, TESTLEN(baseDSS_keylength));
356 result = CryptReleaseContext(hProv, 0);
357 ok(result, "Expected release of CSP provider.\n");
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");
364 /* perform keylength tests */
365 test_keylength_array(hProv, dssDH_keylength, TESTLEN(dssDH_keylength));
367 result = CryptReleaseContext(hProv, 0);
368 ok(result, "Expected release of CSP provider.\n");
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)
376 win_skip("DSSENH and Schannel provider is broken on WinNT4\n");
379 ok(result, "Expected no errors.\n");
381 /* perform keylength tests */
382 test_keylength_array(hProv, dssENH_keylength, TESTLEN(dssENH_keylength));
384 result = CryptReleaseContext(hProv, 0);
385 ok(result, "Expected release of CSP provider.\n");
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");
392 /* perform keylength tests */
393 test_keylength_array(hProv, dssENH_keylength, TESTLEN(dssENH_keylength));
395 result = CryptReleaseContext(hProv, 0);
396 ok(result, "Expected release of CSP provider.\n");
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[] = "";
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}
432 static void test_hash(const struct hash_test *tests, int testLen)
434 HCRYPTPROV hProv = 0;
440 result = CryptAcquireContextA(
441 &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
444 skip("DSSENH is currently not available, skipping hashing tests.\n");
447 ok(result, "Expected no errors.\n");
449 for(i = 0; i < testLen; i++)
451 BYTE* data = tests[i].input;
452 DWORD dataLen = tests[i].dataLen;
455 /* test algid hash */
456 result = CryptCreateHash(hProv, tests[i].algid, 0, 0, &hHash);
457 ok(result, "Expected creation of a hash.\n");
459 result = CryptHashData(hHash, data, dataLen, 0);
460 ok(result, "Expected data to be added to hash.\n");
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());
467 result = CryptGetHashParam(hHash, HP_HASHVAL, hashValue, &hashLen, 0);
468 ok(result, "Expected hash value return.\n");
470 ok(!memcmp(hashValue, tests[i].hash, tests[i].hashLen), "Incorrect hash output.\n");
472 result = CryptHashData(hHash, data, dataLen, 0);
473 ok(!result, "Should not be able to add to hash.\n");
475 result = CryptDestroyHash(hHash);
476 ok(result, "Expected destruction of hash.\n");
478 result = CryptReleaseContext(hProv, 0);
479 ok(result, "Expected release of the DSS Enhanced provider.\n");
482 struct encrypt_test {
487 const BYTE *decrypted;
488 const BYTE *encrypted;
491 static const char dataToEncrypt1[] = "Great performance with Wine.";
492 static const char dataToEncrypt2[] = "Wine implements Windows API";
493 static const char dataToEncrypt3[] = "";
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
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
503 static const BYTE encrypted3DES_3[] = {0xaf, 0x36, 0xc0, 0x3d, 0x78, 0x64, 0xc4, 0x4a};
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
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
513 static const BYTE encrypted3DES112_3[] = {0x04, 0xb3, 0x9c, 0x59, 0x48, 0xc7, 0x2f, 0xd1};
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
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
523 static const BYTE encryptedDES_3[] = {0x35, 0x02, 0xbb, 0x7c, 0x43, 0x5b, 0xf5, 0x59};
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
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
533 static const BYTE encryptedRC2_3[] = {0x26,0x40,0x73,0xfe,0x13,0xbb,0x32,0xa8};
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
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
543 static const BYTE encryptedRC4_3[] = {0x1d};
545 static const struct encrypt_test encrypt_data[] = {
546 {CALG_3DES, 168 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
548 {CALG_3DES, 168 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
550 {CALG_3DES, 168 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
552 {CALG_3DES_112, 112 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
554 {CALG_3DES_112, 112 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
556 {CALG_3DES_112, 112 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
558 {CALG_DES, 56 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
560 {CALG_DES, 56 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
562 {CALG_DES, 56 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
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,
569 {CALG_RC2, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
571 {CALG_RC2, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
573 {CALG_RC4, 40 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
575 {CALG_RC4, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
577 {CALG_RC4, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
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;
586 const char dataToHash[] = "I love working with Wine";
587 unsigned char pbData[36];
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)
598 skip("DSSENH is currently not available, skipping encryption tests.\n");
601 ok(result, "Expected no errors.\n");
603 /* testing various encryption algorithms */
604 for(i = 0; i < testLen; i++)
606 memcpy(pbData, tests[i].plain, tests[i].plainLen);
607 dataLen = tests[i].plainLen;
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");
613 result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
614 ok(result, "Expected data to be added to hash for key derivation.\n");
617 result = CryptDeriveKey(hProv, tests[i].algid, hHash, tests[i].keyLength, &pKey);
618 ok(result, "Expected a derived key.\n");
620 result = CryptDestroyHash(hHash);
621 ok(result, "Expected destruction of hash after deriving key.\n");
623 /* testing CryptEncrypt with ALGID from array */
624 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
625 ok(result, "Expected data encryption.\n");
627 /* Verify we have received expected encrypted data */
628 ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
630 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
631 ok(result, "Expected data decryption.\n");
633 /* Verify we have received expected decrypted data */
634 ok(!memcmp(pbData, tests[i].decrypted, dataLen), "Incorrect decrypted data.\n");
636 result = CryptDestroyKey(pKey);
637 ok(result, "Expected no DestroyKey errors.\n");
639 result = CryptReleaseContext(hProv, 0);
640 ok(result, "Expected release of the provider\n");
643 struct ciphermode_test {
647 const BYTE *encrypted;
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
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
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
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 */
670 static void test_cipher_modes(const struct ciphermode_test *tests, int testLen)
672 HCRYPTPROV hProv = 0;
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;
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)
688 skip("DSSENH is currently not available, skipping block cipher mode tests.\n");
691 ok(result, "Expected no errors.\n");
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");
697 result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
698 ok(result, "Expected data to be added to hash for key derivation.\n");
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");
704 result = CryptDestroyHash(hHash);
705 ok(result, "Expected destruction of hash after deriving key.\n");
707 /* test block cipher modes */
708 for(i = 0; i < testLen; i++)
710 SetLastError(0xdeadbeef);
712 mode = tests[i].cipherMode;
713 memcpy(pbData, plainText, plainLen);
715 result = CryptSetKeyParam(pKey, KP_MODE, (BYTE*)&mode, 0);
716 if(tests[i].expectedResult)
718 ok(result, "Expected setting of KP_MODE, got %x.\n", GetLastError());
720 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
721 ok(result, "Expected data encryption, got %x.\n", GetLastError());
723 /* Verify we have the correct encrypted data */
724 ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
726 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
727 ok(result, "Expected data decryption, got %x.\n", GetLastError());
729 /* Verify we have the correct decrypted data */
730 ok(!memcmp(pbData, (BYTE *)plainText, dataLen), "Incorrect decrypted data.\n");
733 { /* Expected error */
734 ok(!result && GetLastError() == tests[i].expectedError, "Expected %d, got %x.\n",
735 tests[i].expectedError, GetLastError());
738 result = CryptDestroyKey(pKey);
739 ok(result, "Expected no DestroyKey errors.\n");
741 result = CryptReleaseContext(hProv, 0);
742 ok(result, "Expected release of the provider.\n");
745 struct signature_test {
746 const BYTE *privateKey;
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[] = "";
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
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
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)}
813 static void test_signhash_array(HCRYPTPROV hProv, const struct signature_test *tests, int testLen)
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;
825 for (i = 0; i < testLen; i++)
827 DWORD signLen1 = tests[i].dataLen;
828 DWORD signLen2 = tests[i].dataLen;
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());
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());
838 result = CryptHashData(hHash1, tests[i].signData, signLen1, 0);
839 ok(result, "Failed to add data to hash, got %x\n", GetLastError());
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());
845 result = CryptHashData(hHash2, tests[i].signData, signLen2, 0);
846 ok(result, "Failed to add data to hash, got %x\n", GetLastError());
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());
853 result = CryptGetHashParam(hHash1, HP_HASHVAL, hashValue1, &hashLen1, 0);
854 ok(result, "Failed to return hash value.\n");
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());
860 result = CryptGetHashParam(hHash2, HP_HASHVAL, hashValue2, &hashLen2, 0);
861 ok(result, "Failed to return hash value.\n");
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");
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);
872 result = CryptSignHash(hHash1, AT_SIGNATURE, NULL, 0, signValue1, &signLen1);
873 ok(result, "Failed to sign hash, got %x\n", GetLastError());
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);
880 result = CryptSignHash(hHash2, AT_SIGNATURE, NULL, 0, signValue2, &signLen2);
881 ok(result, "Failed to sign hash2, got %x\n", GetLastError());
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.");
888 result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen);
889 ok(result, "Failed to acquire public key length, got %x\n", GetLastError());
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());
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());
900 /* Destroy the private key */
901 result = CryptDestroyKey(privKey);
902 ok(result, "Failed to destroy private key, got %x\n", GetLastError());
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());
908 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
909 ok(result, "Failed to create hash, got %x\n", GetLastError());
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());
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());
919 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
920 ok(result, "Failed to create hash, got %x\n", GetLastError());
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());
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());
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());
935 /* Destroy the public key */
936 result = CryptDestroyKey(pubKey);
937 ok(result, "Failed to destroy public key, got %x\n", GetLastError());
941 static void test_verify_signature(void)
943 HCRYPTPROV hProv = 0;
946 /* acquire base dss provider */
947 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
950 skip("DSSENH is currently not available, skipping signature verification tests.\n");
953 ok(result, "Failed to acquire CSP.\n");
955 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
957 result = CryptReleaseContext(hProv, 0);
958 ok(result, "Failed to release CSP provider.\n");
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");
964 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
966 result = CryptReleaseContext(hProv, 0);
967 ok(result, "Failed to release CSP provider.\n");
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)
974 win_skip("DSSENH and Schannel provider is broken on WinNT4, skipping signature "
975 "verification tests.\n");
978 ok(result, "Failed to acquire CSP.\n");
980 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
982 result = CryptReleaseContext(hProv, 0);
983 ok(result, "Failed to release CSP provider.\n");
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");
989 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
991 result = CryptReleaseContext(hProv, 0);
992 ok(result, "Failed to release CSP provider.\n");
997 test_acquire_context();
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();