dinput: Clear DIA_APPNOMAP BuildActionMap flag with specific device semantic.
[wine.git] / dlls / dssenh / tests / dssenh.c
blobfb9ab8203305741b3ad163254d0a3d155129e68e
1 /*
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
21 #include <string.h>
22 #include <stdio.h>
23 #include "ntstatus.h"
24 #define WIN32_NO_STATUS
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wincrypt.h"
31 static void test_acquire_context(void)
32 { /* failure tests common between all four CSP providers */
34 HCRYPTPROV hProv = 0;
35 BOOL result;
37 /* cannot acquire provider with 0 as Prov Type and NULL as CSP name */
38 SetLastError(0xdeadbeef);
39 result = CryptAcquireContextA(&hProv, NULL, NULL, 0, 0);
40 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
41 "Expected NTE_BAD_PROV_TYPE, got %08lx\n", GetLastError());
43 SetLastError(0xdeadbeef);
44 result = CryptAcquireContextA(&hProv, NULL, NULL, 0, CRYPT_VERIFYCONTEXT);
45 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
46 "Expected NTE_BAD_PROV_TYPE, got %08lx\n", GetLastError());
48 /* flag allows us to delete a keyset, but not of an unknown provider */
49 SetLastError(0xdeadbeef);
50 result = CryptAcquireContextA(&hProv, NULL, NULL, 0, CRYPT_DELETEKEYSET);
51 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
52 "Expected NTE_BAD_PROV_TYPE, got %08lx\n", GetLastError());
54 /* cannot acquire along with PROV_RSA_SIG, not compatible */
55 SetLastError(0xdeadbeef);
56 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_RSA_SIG, 0);
57 ok(!result && GetLastError() == NTE_PROV_TYPE_NO_MATCH,
58 "Expected NTE_PROV_TYPE_NO_MATCH, got %08lx\n", GetLastError());
60 /* cannot acquire along with MS_DEF_RSA_SIG_PROV_A, not compatible */
61 SetLastError(0xdeadbeef);
62 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_RSA_SIG_PROV_A, PROV_DSS, 0);
63 ok(!result && GetLastError() == NTE_KEYSET_NOT_DEF,
64 "Expected NTE_KEYSET_NOT_DEF, got %08lx\n", GetLastError());
66 /* cannot acquire provider with 0 as Prov Type */
67 SetLastError(0xdeadbeef);
68 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, 0, 0);
69 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
70 "Expected NTE_BAD_PROV_TYPE, got %08lx\n", GetLastError());
72 /* test base DSS provider (PROV_DSS) */
74 SetLastError(0xdeadbeef);
75 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS, 0);
76 if (!result)
78 ok(GetLastError() == NTE_BAD_KEYSET, "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
79 SetLastError(0xdeadbeef);
80 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS, CRYPT_NEWKEYSET);
82 ok(result, "CryptAcquireContextA succeeded\n");
84 result = CryptReleaseContext(hProv, 0);
85 ok(result, "CryptReleaseContext failed.\n");
87 result = CryptAcquireContextA(
88 &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
89 if(!result)
91 skip("DSS csp is currently not available, skipping tests.\n");
92 return;
94 ok(result, "Expected no errors.\n");
96 result = CryptReleaseContext(hProv, 0);
97 ok(result, "Expected release of the provider.\n");
99 result = CryptAcquireContextA(
100 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
101 ok(result || GetLastError() == NTE_EXISTS, "Expected no errors or NTE_EXISTS\n");
103 if (result)
105 result = CryptReleaseContext(hProv, 0);
106 ok(result, "Expected release of the provider.\n");
109 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS, 0);
110 ok(result, "Expected no errors.\n");
112 result = CryptReleaseContext(hProv, 0);
113 ok(result, "Expected release of the provider.\n");
115 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
116 ok(result, "Expected no errors.\n");
118 /* test DSS Diffie Hellman provider (PROV_DSS_DH) */
120 result = CryptAcquireContextA(
121 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
122 ok(result, "Expected no errors.\n");
124 result = CryptReleaseContext(hProv, 0);
125 ok(result, "Expected release of the provider.\n");
127 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS_DH, 0);
128 ok(result, "Expected no errors.\n");
130 result = CryptReleaseContext(hProv, 0);
131 ok(result, "Expected release of the provider.\n");
133 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, 0);
134 ok(result, "Expected no errors.\n");
136 /* test DSS Enhanced provider (MS_ENH_DSS_DH_PROV_A) */
138 SetLastError(0xdeadbeef);
139 result = CryptAcquireContextA(
140 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
141 ok(result, "Expected no errors.\n");
143 result = CryptReleaseContext(hProv, 0);
144 ok(result, "Expected release of the provider.\n");
146 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, 0);
147 ok(result, "Expected no errors.\n");
149 result = CryptReleaseContext(hProv, 0);
150 ok(result, "Expected release of the provider.\n");
152 /* test DSS Schannel provider (PROV_DH_SCHANNEL) */
154 result = CryptAcquireContextA(
155 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, CRYPT_VERIFYCONTEXT);
156 ok(result, "Expected no errors.\n");
158 result = CryptReleaseContext(hProv, 0);
159 ok(result, "Expected release of the provider.\n");
161 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DH_SCHANNEL, 0);
162 ok(result, "Expected no errors.\n");
164 result = CryptReleaseContext(hProv, 0);
165 ok(result, "Expected release of the provider.\n");
167 result = CryptAcquireContextA(
168 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, 0);
169 ok(result, "Expected no errors.\n");
171 result = CryptReleaseContext(hProv, 0);
172 ok(result, "Expected release of the provider.\n");
174 /* failure tests, cannot acquire context because the key container already exists */
175 SetLastError(0xdeadbeef);
176 result = CryptAcquireContextA(
177 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
178 ok(!result && GetLastError() == NTE_EXISTS,
179 "Expected NTE_EXISTS, got %08lx\n", GetLastError());
181 SetLastError(0xdeadbeef);
182 result = CryptAcquireContextA(
183 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
184 ok(!result && GetLastError() == NTE_EXISTS,
185 "Expected NTE_EXISTS, got %08lx\n", GetLastError());
187 SetLastError(0xdeadbeef);
188 result = CryptAcquireContextA(
189 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, CRYPT_NEWKEYSET);
190 ok(!result && GetLastError() == NTE_EXISTS,
191 "Expected NTE_EXISTS, got %08lx\n", GetLastError());
194 struct keylength_test {
195 ALG_ID algid;
196 DWORD flags;
197 BOOL expectedResult;
198 DWORD expectedError;
199 DWORD brokenError;
200 int todo_result;
201 int todo_error;
204 static const struct keylength_test baseDSS_keylength[] = {
205 /* AT_KEYEXCHANGE is not supported by the base DSS provider */
206 {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
207 {AT_KEYEXCHANGE, 512 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
208 {AT_KEYEXCHANGE, 1024 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
209 {AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
210 /* min 512 max 1024 increment by 64 */
211 {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
212 {AT_SIGNATURE, 512 << 16, TRUE},
213 {AT_SIGNATURE, 513 << 16, FALSE, STATUS_INVALID_PARAMETER, NTE_FAIL},
214 {AT_SIGNATURE, 768 << 16, TRUE},
215 {AT_SIGNATURE, 1024 << 16, TRUE},
216 {AT_SIGNATURE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
217 /* CALG_DH_EPHEM is not supported by the base DSS provider */
218 {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
219 {CALG_DH_EPHEM, 512 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
220 {CALG_DH_EPHEM, 1024 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
221 {CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
222 /* CALG_DH_SF is not supported by the base DSS provider */
223 {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
224 {CALG_DH_SF, 512 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
225 {CALG_DH_SF, 1024 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
226 {CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
227 /* min 512 max 1024, increment by 64 */
228 {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
229 {CALG_DSS_SIGN, 512 << 16, TRUE},
230 {CALG_DSS_SIGN, 513 << 16, FALSE, STATUS_INVALID_PARAMETER, NTE_FAIL},
231 {CALG_DSS_SIGN, 768 << 16, TRUE},
232 {CALG_DSS_SIGN, 1024 << 16, TRUE},
233 {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
236 static const struct keylength_test dssDH_keylength[] = {
237 /* min 512 max 1024, increment by 64 */
238 {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_FLAGS},
239 {AT_KEYEXCHANGE, 512 << 16, TRUE, 0, 0, 1},
240 {AT_KEYEXCHANGE, 513 << 16, FALSE, NTE_BAD_FLAGS, 0, 0, 1},
241 {AT_KEYEXCHANGE, 768 << 16, TRUE, 0, 0, 1},
242 {AT_KEYEXCHANGE, 1024 << 16, TRUE, 0, 0, 1},
243 {AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
244 {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
245 {AT_SIGNATURE, 512 << 16, TRUE},
246 {AT_SIGNATURE, 513 << 16, FALSE, STATUS_INVALID_PARAMETER, NTE_FAIL},
247 {AT_SIGNATURE, 768 << 16, TRUE},
248 {AT_SIGNATURE, 1024 << 16, TRUE},
249 {AT_SIGNATURE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
250 {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_FLAGS},
251 {CALG_DH_EPHEM, 512 << 16, TRUE, 0, 0, 1},
252 {CALG_DH_EPHEM, 513 << 16, FALSE, NTE_BAD_FLAGS, 0, 0, 1},
253 {CALG_DH_EPHEM, 768 << 16, TRUE, 0, 0, 1},
254 {CALG_DH_EPHEM, 1024 << 16, TRUE, 0, 0, 1},
255 {CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_FLAGS},
256 {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_FLAGS},
257 {CALG_DH_SF, 512 << 16, TRUE, 0, 0, 1},
258 {CALG_DH_SF, 513 << 16, FALSE, NTE_BAD_FLAGS, 0, 0, 1},
259 {CALG_DH_SF, 768 << 16, TRUE, 0, 0, 1},
260 {CALG_DH_SF, 1024 << 16, TRUE, 0, 0, 1},
261 {CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_FLAGS},
262 {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
263 {CALG_DSS_SIGN, 512 << 16, TRUE},
264 {CALG_DSS_SIGN, 513 << 16, FALSE, STATUS_INVALID_PARAMETER, NTE_FAIL},
265 {CALG_DSS_SIGN, 768 << 16, TRUE},
266 {CALG_DSS_SIGN, 1024 << 16, TRUE},
267 {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
270 static const struct keylength_test dssENH_keylength[] = {
271 /* min 512 max 1024 (AT_KEYEXCHANGE, CALG_DH_EPHEM, CALG_DH_SF max 4096), increment by 64*/
272 {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_FLAGS},
273 {AT_KEYEXCHANGE, 512 << 16, TRUE, 0, 0, 1},
274 {AT_KEYEXCHANGE, 513 << 16, FALSE, NTE_BAD_FLAGS, 0, 0, 1},
275 {AT_KEYEXCHANGE, 768 << 16, TRUE, 0, 0, 1},
276 {AT_KEYEXCHANGE, 1024 << 16, TRUE, 0, 0, 1},
277 {AT_KEYEXCHANGE, 1088 << 16, TRUE, 0, 0, 1},
278 {AT_KEYEXCHANGE, 2048 << 16, TRUE, 0, 0, 1},
279 /* Keylength too large - test bot timeout.
280 {AT_KEYEXCHANGE, 3072 << 16, TRUE},
281 {AT_KEYEXCHANGE, 4096 << 16, TRUE}, */
282 {AT_KEYEXCHANGE, 4160 << 16, FALSE, NTE_BAD_FLAGS},
283 {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
284 {AT_SIGNATURE, 512 << 16, TRUE},
285 {AT_SIGNATURE, 513 << 16, FALSE, STATUS_INVALID_PARAMETER, NTE_FAIL},
286 {AT_SIGNATURE, 768 << 16, TRUE},
287 {AT_SIGNATURE, 1024 << 16, TRUE},
288 {AT_SIGNATURE, 1032 << 16, FALSE, NTE_BAD_FLAGS},
289 {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_FLAGS},
290 {CALG_DH_EPHEM, 512 << 16, TRUE, 0, 0, 1},
291 {CALG_DH_EPHEM, 513 << 16, FALSE, NTE_BAD_FLAGS, 0, 0, 1},
292 {CALG_DH_EPHEM, 768 << 16, TRUE, 0, 0, 1},
293 {CALG_DH_EPHEM, 1024 << 16, TRUE, 0, 0, 1},
294 {CALG_DH_EPHEM, 1040 << 16, FALSE, NTE_BAD_FLAGS},
295 {CALG_DH_EPHEM, 1088 << 16, TRUE, 0, 0, 1},
296 {CALG_DH_EPHEM, 4160 << 16, FALSE, NTE_BAD_FLAGS},
297 {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_FLAGS},
298 {CALG_DH_SF, 512 << 16, TRUE, 0, 0, 1},
299 {CALG_DH_SF, 513 << 16, FALSE, NTE_BAD_FLAGS, 0, 0, 1},
300 {CALG_DH_SF, 768 << 16, TRUE, 0, 0, 1},
301 {CALG_DH_SF, 1024 << 16, TRUE, 0, 0, 1},
302 {CALG_DH_SF, 1032 << 16, FALSE, NTE_BAD_FLAGS},
303 {CALG_DH_SF, 1088 << 16, TRUE, 0, 0, 1},
304 {CALG_DH_SF, 4160 << 16, FALSE, NTE_BAD_FLAGS},
305 {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
306 {CALG_DSS_SIGN, 512 << 16, TRUE},
307 {CALG_DSS_SIGN, 513 << 16, FALSE, STATUS_INVALID_PARAMETER, NTE_FAIL},
308 {CALG_DSS_SIGN, 768 << 16, TRUE},
309 {CALG_DSS_SIGN, 1024 << 16, TRUE},
310 {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
313 static void test_keylength_array(HCRYPTPROV hProv,const struct keylength_test *tests, int testLen)
315 HCRYPTKEY key;
316 BOOL result;
317 int i;
319 for (i = 0; i < testLen; i++)
321 SetLastError(0xdeadbeef);
322 result = CryptGenKey(hProv, tests[i].algid, tests[i].flags, &key);
324 /* success */
325 if (tests[i].expectedResult)
327 todo_wine_if (tests[i].todo_result) ok(result, "%d: got %08lx\n", i, GetLastError());
328 if (result)
330 result = CryptDestroyKey(key);
331 ok(result, "%d: got %08lx\n", i, GetLastError());
334 else
336 todo_wine_if (tests[i].todo_result) ok(!result, "%d: got %lx\n", i, GetLastError());
337 todo_wine_if (tests[i].todo_error)
338 ok(GetLastError() == tests[i].expectedError ||
339 broken(GetLastError() == tests[i].brokenError), "%d: got %08lx\n", i, GetLastError());
344 static void test_keylength(void)
346 HCRYPTPROV hProv = 0;
347 HCRYPTKEY key;
348 BOOL result;
350 /* acquire base dss provider */
351 result = CryptAcquireContextA(
352 &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
353 if(!result)
355 skip("DSSENH is currently not available, skipping key length tests.\n");
356 return;
358 ok(result, "Expected no errors.\n");
360 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &key);
361 ok(result, "Expected no errors.\n");
363 result = CryptDestroyKey(key);
364 ok(result, "Expected no errors.\n");
366 /* perform keylength tests */
367 test_keylength_array(hProv, baseDSS_keylength, ARRAY_SIZE(baseDSS_keylength));
369 result = CryptReleaseContext(hProv, 0);
370 ok(result, "Expected release of CSP provider.\n");
372 /* acquire diffie hellman dss provider */
373 result = CryptAcquireContextA(
374 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
375 ok(result, "Expected no errors.\n");
377 /* perform keylength tests */
378 test_keylength_array(hProv, dssDH_keylength, ARRAY_SIZE(dssDH_keylength));
380 result = CryptReleaseContext(hProv, 0);
381 ok(result, "Expected release of CSP provider.\n");
383 /* acquire enhanced dss provider */
384 SetLastError(0xdeadbeef);
385 result = CryptAcquireContextA(
386 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
387 ok(result, "Expected no errors.\n");
389 /* perform keylength tests */
390 test_keylength_array(hProv, dssENH_keylength, ARRAY_SIZE(dssENH_keylength));
392 result = CryptReleaseContext(hProv, 0);
393 ok(result, "Expected release of CSP provider.\n");
395 /* acquire schannel dss provider */
396 result = CryptAcquireContextA(
397 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, CRYPT_VERIFYCONTEXT);
398 ok(result, "Expected no errors.\n");
400 /* perform keylength tests */
401 test_keylength_array(hProv, dssENH_keylength, ARRAY_SIZE(dssENH_keylength));
403 result = CryptReleaseContext(hProv, 0);
404 ok(result, "Expected release of CSP provider.\n");
407 struct hash_test {
408 ALG_ID algid;
409 BYTE* input;
410 DWORD dataLen;
411 BYTE hash[20];
412 DWORD hashLen;
415 static const char testHashVal1[] = "I love working with Wine";
416 static const char testHashVal2[] = "Wine is not an emulater.";
417 static const char testHashVal3[] = "";
419 static const struct hash_test hash_data[] = {
420 {CALG_MD5, (BYTE *)testHashVal1, sizeof(testHashVal1),
421 {0x4f, 0xf4, 0xd0, 0xdf, 0xe8, 0xf6, 0x6b, 0x1b,
422 0x87, 0xea, 0xca, 0x3d, 0xe8, 0x3c, 0xdd, 0xae}, 16},
423 {CALG_MD5, (BYTE *)testHashVal2, sizeof(testHashVal2),
424 {0x80, 0x5c, 0x1c, 0x0e, 0x79, 0x70, 0xd9, 0x38,
425 0x04, 0x46, 0x19, 0xbe, 0x38, 0x1f, 0xef, 0xe1}, 16},
426 {CALG_MD5, (BYTE *)testHashVal3, sizeof(testHashVal3),
427 {0x93, 0xb8, 0x85, 0xad, 0xfe, 0x0d, 0xa0, 0x89,
428 0xcd, 0xf6, 0x34, 0x90, 0x4f, 0xd5, 0x9f, 0x71}, 16},
429 {CALG_SHA, (BYTE *)testHashVal1, sizeof(testHashVal1),
430 {0x2a, 0xd0, 0xc9, 0x42, 0xfb, 0x73, 0x02, 0x48, 0xbb, 0x5f,
431 0xc2, 0xa4, 0x78, 0xdd, 0xe4, 0x3b, 0xfc, 0x76, 0xe9, 0xe2}, 20},
432 {CALG_SHA, (BYTE *)testHashVal2, sizeof(testHashVal2),
433 {0xfd, 0xfc, 0xab, 0x3a, 0xde, 0x33, 0x01, 0x38, 0xfe, 0xbb,
434 0xc3, 0x13, 0x84, 0x20, 0x9e, 0x55, 0x94, 0x8d, 0xc6, 0x05}, 20},
435 {CALG_SHA, (BYTE *)testHashVal3, sizeof(testHashVal3),
436 {0x5b, 0xa9, 0x3c, 0x9d, 0xb0, 0xcf, 0xf9, 0x3f, 0x52, 0xb5,
437 0x21, 0xd7, 0x42, 0x0e, 0x43, 0xf6, 0xed, 0xa2, 0x78, 0x4f}, 20}
440 static void test_hash(const struct hash_test *tests, int testLen)
442 HCRYPTPROV hProv = 0;
443 HCRYPTHASH hHash;
444 BYTE hashValue[36];
445 BOOL result;
446 int i;
448 result = CryptAcquireContextA(
449 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
450 if(!result)
452 skip("DSSENH is currently not available, skipping hashing tests.\n");
453 return;
455 ok(result, "Expected no errors.\n");
457 for(i = 0; i < testLen; i++)
459 BYTE* data = tests[i].input;
460 DWORD dataLen = tests[i].dataLen;
461 DWORD hashLen;
463 /* test algid hash */
464 result = CryptCreateHash(hProv, tests[i].algid, 0, 0, &hHash);
465 ok(result, "Expected creation of a hash.\n");
467 result = CryptHashData(hHash, data, dataLen, 0);
468 ok(result, "Expected data to be added to hash.\n");
470 dataLen = sizeof(DWORD);
471 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashLen, &dataLen, 0);
472 ok(result && (hashLen == tests[i].hashLen), "Expected %ld hash len, got %ld.Error: %lx\n",
473 tests[i].hashLen, hashLen, GetLastError());
475 dataLen = 0xdeadbeef;
476 result = CryptGetHashParam(hHash, HP_HASHVAL, 0, &dataLen, 0);
477 ok(result, "Expected hash value return.\n");
478 ok(dataLen == hashLen, "Expected hash length to match.\n");
480 hashLen = 0xdeadbeef;
481 result = CryptGetHashParam(hHash, HP_HASHVAL, hashValue, &hashLen, 0);
482 ok(result, "Expected hash value return.\n");
484 ok(dataLen == hashLen, "Expected hash length to match.\n");
485 ok(!memcmp(hashValue, tests[i].hash, tests[i].hashLen), "Incorrect hash output.\n");
487 result = CryptHashData(hHash, data, dataLen, 0);
488 ok(!result, "Should not be able to add to hash.\n");
490 result = CryptDestroyHash(hHash);
491 ok(result, "Expected destruction of hash.\n");
493 result = CryptReleaseContext(hProv, 0);
494 ok(result, "Expected release of the DSS Enhanced provider.\n");
497 struct encrypt_test {
498 ALG_ID algid;
499 DWORD keyLength;
500 const char *plain;
501 DWORD plainLen;
502 const BYTE *decrypted;
503 const BYTE *encrypted;
506 static const char dataToEncrypt1[] = "Great performance with Wine.";
507 static const char dataToEncrypt2[] = "Wine implements Windows API";
508 static const char dataToEncrypt3[] = "";
510 static const BYTE encrypted3DES_1[] = {
511 0x6c,0x60,0x19,0x41,0x27,0xc1,0x16,0x69, 0x6f,0x96,0x0c,0x2e,0xa4,0x5f,0xf5,0x6a,
512 0xed,0x4b,0xec,0xd4,0x92,0x0c,0xe2,0x34, 0xe1,0x4a,0xb5,0xe2,0x05,0x43,0xfe,0x17
514 static const BYTE encrypted3DES_2[] = {
515 0x17,0xeb,0x80,0xde,0xac,0x4d,0x9e,0xd0, 0xa9,0xae,0x74,0xb5,0x86,0x1a,0xea,0xb4,
516 0x96,0x27,0x5d,0x75,0x4f,0xdd,0x87,0x60, 0xfc,0xaf,0xa1,0x82,0x83,0x09,0xf1,0xca
518 static const BYTE encrypted3DES_3[] = {0xaf, 0x36, 0xc0, 0x3d, 0x78, 0x64, 0xc4, 0x4a};
520 static const BYTE encrypted3DES112_1[] = {
521 0xb3,0xf8,0x4b,0x08,0xd6,0x23,0xcb,0xca, 0x43,0x26,0xd9,0x9f,0x6b,0x99,0x09,0xe9,
522 0x8c,0x4c,0x7d,0xef,0x49,0xda,0x0b,0x44, 0xcc,0x8d,0x06,0x6b,0xed,0xb7,0xf1,0x67
524 static const BYTE encrypted3DES112_2[] = {
525 0xdc,0xcf,0x93,0x11,0x7a,0xe4,0xcd,0x3f, 0x11,0xd8,0xe0,0x1e,0xe0,0x8d,0x9c,0xba,
526 0x97,0x5d,0x74,0x4d,0x83,0x03,0x5c,0xf2, 0x01,0xaf,0xed,0x7a,0x87,0x8f,0x88,0x8b
528 static const BYTE encrypted3DES112_3[] = {0x04, 0xb3, 0x9c, 0x59, 0x48, 0xc7, 0x2f, 0xd1};
530 static const BYTE encryptedDES_1[] = {
531 0x3d,0xdc,0x54,0xaf,0x66,0x72,0x4e,0xef, 0x9d,0x35,0x02,0xc2,0x1a,0xf4,0x1f,0x01,
532 0xb1,0xaf,0x13,0xd9,0xbe,0x7b,0xd4,0xf3, 0xf5,0x9d,0x2a,0xd8,0x32,0x90,0xe9,0x0b
534 static const BYTE encryptedDES_2[] = {
535 0xa8,0x05,0xd7,0xe9,0x61,0xf4,0x6c,0xce, 0x95,0x2b,0x52,0x08,0x25,0x03,0x30,0xac,
536 0xd7,0xe7,0xd3,0x07,0xb2,0x68,0x63,0x7b, 0xe3,0xab,0x26,0x1e,0x5c,0xec,0x42,0x4f
538 static const BYTE encryptedDES_3[] = {0x35, 0x02, 0xbb, 0x7c, 0x43, 0x5b, 0xf5, 0x59};
540 static const BYTE encryptedRC2_1[] = {
541 0x9e,0xcb,0xa2,0x27,0xc2,0xec,0x10,0xe0, 0x94,0xb3,0xc3,0x9d,0x7d,0xe2,0x12,0xe4,
542 0xb0,0xde,0xd9,0x46,0xca,0x1f,0xa6,0xfa, 0xa4,0x79,0x08,0x59,0xa6,0x00,0x62,0x16
544 static const BYTE encryptedRC2_2[] = {
545 0x29,0x06,0xfd,0xa1,0xe0,0x88,0x89,0xb0, 0x4d,0x7f,0x96,0x9d,0x2c,0x44,0xa1,0xd2,
546 0xbe,0xc6,0xaf,0x10,0xb8,0x86,0x68,0x1b, 0x1d,0x9f,0x3c,0xc4,0x12,0x02,0xbc,0x73
548 static const BYTE encryptedRC2_3[] = {0x26,0x40,0x73,0xfe,0x13,0xbb,0x32,0xa8};
550 static const BYTE encryptedRC4_1[] = {
551 0x5a,0x48,0xeb,0x16,0x96,0x23,0x16,0xb7, 0xbb,0x36,0xe8,0x43,0x88,0x74,0xb1,0x9d,
552 0x96,0xf0,0x84,0x0f,0x5a,0x56,0xf9,0x62, 0xae,0xb5,0x4a,0xce,0x52
554 static const BYTE encryptedRC4_2[] = {
555 0x4a,0x53,0xe0,0x12,0xc2,0x6a,0x0b,0xa2, 0xa5,0x35,0xea,0x54,0x8b,0x61,0xac,0xde,
556 0xa4,0xb9,0x9d,0x02,0x41,0x49,0xaa,0x15, 0x86,0x8b,0x66,0xe0
558 static const BYTE encryptedRC4_3[] = {0x1d};
560 static const struct encrypt_test encrypt_data[] = {
561 {CALG_3DES, 168 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
562 encrypted3DES_1},
563 {CALG_3DES, 168 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
564 encrypted3DES_2},
565 {CALG_3DES, 168 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
566 encrypted3DES_3},
567 {CALG_3DES_112, 112 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
568 encrypted3DES112_1},
569 {CALG_3DES_112, 112 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
570 encrypted3DES112_2},
571 {CALG_3DES_112, 112 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
572 encrypted3DES112_3},
573 {CALG_DES, 56 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
574 encryptedDES_1},
575 {CALG_DES, 56 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
576 encryptedDES_2},
577 {CALG_DES, 56 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
578 encryptedDES_3},
579 /* CALG_RC2 key unexpected results under Win2K when default key length is used, here we use
580 minimum length because Win2K's DSSENH provider has a different default key length compared
581 to the younger operating systems, though there is no default key len issue with CALG_RC4 */
582 {CALG_RC2, 40 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
583 encryptedRC2_1},
584 {CALG_RC2, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
585 encryptedRC2_2},
586 {CALG_RC2, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
587 encryptedRC2_3},
588 {CALG_RC4, 40 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
589 encryptedRC4_1},
590 {CALG_RC4, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
591 encryptedRC4_2},
592 {CALG_RC4, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
593 encryptedRC4_3}
596 static void test_data_encryption(const struct encrypt_test *tests, int testLen)
597 { /* Here we test the same encryption ciphers as the RSAENH cryptographic service provider */
598 HCRYPTPROV hProv = 0;
599 HCRYPTKEY pKey = 0;
600 HCRYPTHASH hHash;
601 const char dataToHash[] = "I love working with Wine";
602 unsigned char pbData[36];
603 DWORD dataLen;
604 BOOL result;
605 int i;
607 /* acquire dss enhanced provider */
608 SetLastError(0xdeadbeef);
609 result = CryptAcquireContextA(
610 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
611 if (!result)
613 skip("DSSENH is currently not available, skipping encryption tests.\n");
614 return;
616 ok(result, "Expected no errors.\n");
618 /* testing various encryption algorithms */
619 for(i = 0; i < testLen; i++)
621 memcpy(pbData, tests[i].plain, tests[i].plainLen);
622 dataLen = tests[i].plainLen;
624 SetLastError(0xdeadbeef);
625 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
626 ok(result, "Expected creation of a MD5 hash for key derivation.\n");
628 result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
629 ok(result, "Expected data to be added to hash for key derivation.\n");
631 /* Derive key */
632 result = CryptDeriveKey(hProv, tests[i].algid, hHash, tests[i].keyLength, &pKey);
633 if (!result)
635 skip("skipping encryption tests\n");
636 return;
638 ok(result, "Expected a derived key.\n");
640 result = CryptDestroyHash(hHash);
641 ok(result, "Expected destruction of hash after deriving key.\n");
643 /* testing CryptEncrypt with ALGID from array */
644 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
645 ok(result, "Expected data encryption.\n");
647 /* Verify we have received expected encrypted data */
648 ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
650 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
651 ok(result, "Expected data decryption.\n");
653 /* Verify we have received expected decrypted data */
654 ok(!memcmp(pbData, tests[i].decrypted, dataLen) ||
655 broken(tests[i].algid == CALG_RC4), "Incorrect decrypted data.\n");
657 result = CryptDestroyKey(pKey);
658 ok(result, "Expected no DestroyKey errors.\n");
660 result = CryptReleaseContext(hProv, 0);
661 ok(result, "Expected release of the provider\n");
664 struct ciphermode_test {
665 DWORD cipherMode;
666 BOOL expectedResult;
667 DWORD expectedError;
668 const BYTE *encrypted;
671 static const BYTE encryptedCFB[] = {
672 0x51,0x15,0x77,0xab,0x62,0x1f,0x7d,0xcb, 0x35,0x1e,0xd8,0xd3,0x2a,0x00,0xf0,0x94,
673 0x7c,0xa5,0x28,0xda,0xb8,0x81,0x15,0x99, 0xd1,0xd5,0x06,0x1d,0xd3,0x46,0x7e,0xca
675 static const BYTE encryptedCBC[] = {
676 0x8f,0x7b,0x56,0xeb,0xad,0x4d,0x76,0xc2, 0xd5,0x1d,0xf0,0x60,0x9d,0xde,0x96,0xe8,
677 0xb7,0x7b,0xeb,0x4b,0xee,0x3f,0xae,0x05, 0x20,0xf5,0xe0,0x75,0xa0,0x1d,0xf9,0x39
679 static const BYTE encryptedECB[] = {
680 0x8f,0x7b,0x56,0xeb,0xad,0x4d,0x76,0xc2, 0x8b,0xe0,0x4e,0xe4,0x98,0x4f,0xb8,0x3b,
681 0xf3,0xeb,0x6f,0x0a,0x57,0x91,0xdd,0xc7, 0x34,0x5d,0x4c,0xa3,0x7e,0x97,0xbf,0xee
684 static const struct ciphermode_test ciphermode_data[] = {
685 {CRYPT_MODE_CFB, TRUE, 0xdeadbeef, encryptedCFB}, /* Testing cipher block chaining */
686 {CRYPT_MODE_CBC, TRUE, 0xdeadbeef, encryptedCBC}, /* Testing cipher feedback */
687 {CRYPT_MODE_ECB, TRUE, 0xdeadbeef, encryptedECB}, /* Testing electronic codebook */
688 {CRYPT_MODE_OFB, FALSE, NTE_BAD_DATA}/* DSSENH does not support Output Feedback cipher mode */
691 static void test_cipher_modes(const struct ciphermode_test *tests, int testLen)
693 HCRYPTPROV hProv = 0;
694 HCRYPTKEY pKey = 0;
695 HCRYPTHASH hHash;
696 const char plainText[] = "Testing block cipher modes.";
697 const char dataToHash[] = "GSOC is awesome!";
698 unsigned char pbData[36];
699 int plainLen = sizeof(plainText), i;
700 DWORD mode, dataLen;
701 BOOL result;
703 /* acquire dss enhanced provider */
704 SetLastError(0xdeadbeef);
705 result = CryptAcquireContextA(
706 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
707 if (!result)
709 skip("DSSENH is currently not available, skipping block cipher mode tests.\n");
710 return;
712 ok(result, "Expected no errors.\n");
714 SetLastError(0xdeadbeef);
715 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
716 ok(result, "Expected creation of a MD5 hash for key derivation.\n");
718 result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
719 ok(result, "Expected data to be added to hash for key derivation.\n");
721 /* Derive a CALG_RC2 key, but could be any other encryption cipher */
722 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &pKey);
723 if (!result)
725 skip("skipping cipher mode tests\n");
726 return;
728 ok(result, "Expected a derived key.\n");
730 result = CryptDestroyHash(hHash);
731 ok(result, "Expected destruction of hash after deriving key.\n");
733 /* the default algorithm is CBC, test that without setting a mode */
734 mode = 0xdeadbeef;
735 dataLen = sizeof(mode);
736 result = CryptGetKeyParam(pKey, KP_MODE, (BYTE*)&mode, &dataLen, 0);
737 ok(result, "Expected getting of KP_MODE, got %lx.\n", GetLastError());
738 ok(mode == CRYPT_MODE_CBC, "Default mode should be CBC\n");
740 memcpy(pbData, plainText, plainLen);
741 dataLen = plainLen;
742 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
743 ok(result, "Expected data encryption, got %lx.\n", GetLastError());
745 /* Verify we have the correct encrypted data */
746 ok(!memcmp(pbData, tests[1].encrypted, dataLen), "Incorrect encrypted data.\n");
748 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
749 ok(result, "Expected data decryption, got %lx.\n", GetLastError());
751 /* Verify we have the correct decrypted data */
752 ok(!memcmp(pbData, (BYTE *)plainText, dataLen), "Incorrect decrypted data.\n");
754 /* test block cipher modes */
755 for(i = 0; i < testLen; i++)
757 SetLastError(0xdeadbeef);
758 dataLen = plainLen;
759 mode = tests[i].cipherMode;
760 memcpy(pbData, plainText, plainLen);
762 result = CryptSetKeyParam(pKey, KP_MODE, (BYTE*)&mode, 0);
763 if(tests[i].expectedResult)
765 ok(result, "Expected setting of KP_MODE, got %lx.\n", GetLastError());
767 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
768 ok(result, "Expected data encryption, got %lx.\n", GetLastError());
770 /* Verify we have the correct encrypted data */
771 ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
773 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
774 ok(result, "Expected data decryption, got %lx.\n", GetLastError());
776 /* Verify we have the correct decrypted data */
777 ok(!memcmp(pbData, (BYTE *)plainText, dataLen), "Incorrect decrypted data.\n");
779 else
780 { /* Expected error */
781 ok(!result && GetLastError() == tests[i].expectedError, "Expected %ld, got %lx.\n",
782 tests[i].expectedError, GetLastError());
785 result = CryptDestroyKey(pKey);
786 ok(result, "Expected no DestroyKey errors.\n");
788 result = CryptReleaseContext(hProv, 0);
789 ok(result, "Expected release of the provider.\n");
792 struct signature_test {
793 const BYTE *privateKey;
794 DWORD keyLen;
795 BYTE* signData;
796 DWORD dataLen;
799 static const char dataToSign1[] = "Put your hands up for Cryptography :)";
800 static const char dataToSign2[] = "With DSSENH implemented, applications requiring it will now work.";
801 static const char dataToSign3[] = "";
803 static const BYTE AT_SIGNATURE_PrivateKey[] = {
804 0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00, 0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,
805 0x01,0xd1,0xfc,0x7a,0x70,0x53,0xb2,0x48, 0x70,0x23,0x19,0x1f,0x3c,0xe1,0x26,0x14,
806 0x7e,0x9f,0x0f,0x7f,0x33,0x5e,0x2b,0xf7, 0xca,0x01,0x74,0x8c,0xb4,0xfd,0xf6,0x44,
807 0x95,0x35,0x56,0xaa,0x4d,0x62,0x48,0xe2, 0xd1,0xa2,0x7e,0x6e,0xeb,0xd6,0xcc,0x7c,
808 0xe8,0xfd,0x21,0x9a,0xa2,0xfd,0x7a,0x9d, 0x1a,0x38,0x69,0x87,0x39,0x5a,0x91,0xc0,
809 0x52,0x2b,0x9f,0x2a,0x54,0x78,0x37,0x82, 0x9a,0x70,0x57,0xab,0xec,0x93,0x8e,0xac,
810 0x73,0x04,0xe8,0x53,0x72,0x72,0x32,0xc6, 0xcb,0xef,0x47,0x98,0x3c,0x56,0x49,0x62,
811 0xcb,0xbb,0xe7,0x34,0x84,0xa6,0x72,0x3a, 0xbe,0x26,0x46,0x86,0xca,0xcb,0x35,0x62,
812 0x4f,0x19,0x18,0x0b,0xb0,0x78,0xae,0xd5, 0x42,0xdf,0x26,0xdb,0x85,0x63,0x77,0x85,
813 0x01,0x3b,0x32,0xbe,0x5c,0xf8,0x05,0xc8, 0xde,0x17,0x7f,0xb9,0x03,0x82,0xfa,0xf1,
814 0x9e,0x32,0x73,0xfa,0x8d,0xea,0xa3,0x30, 0x48,0xe2,0xdf,0x5a,0xcb,0x83,0x3d,0xff,
815 0x56,0xe9,0xc0,0x94,0xf8,0x6d,0xb3,0xaf, 0x4a,0x97,0xb9,0x43,0x0e,0xd4,0x28,0x98,
816 0x57,0x2e,0x3a,0xca,0xde,0x6f,0x45,0x0d, 0xfb,0x58,0xec,0x78,0x34,0x2e,0x46,0x4d,
817 0xfe,0x98,0x02,0xbb,0xef,0x07,0x1a,0x13, 0xb6,0xc2,0x2c,0x06,0xd9,0x0c,0xc4,0xb0,
818 0x4c,0x3a,0xfc,0x01,0x63,0xb5,0x5a,0x5d, 0x2d,0x9c,0x47,0x04,0x67,0x51,0xf2,0x52,
819 0xf5,0x82,0x36,0xeb,0x6e,0x66,0x58,0x4c, 0x10,0x2c,0x29,0x72,0x4a,0x6f,0x6b,0x6c,
820 0xe0,0x93,0x31,0x42,0xf6,0xda,0xfa,0x5b, 0x22,0x43,0x9b,0x1a,0x98,0x71,0xe7,0x41,
821 0x74,0xe9,0x12,0xa4,0x1f,0x27,0x0a,0x63, 0x94,0x49,0xd7,0xad,0xa5,0xc4,0x5c,0xc3,
822 0xc9,0x70,0xb3,0x7b,0x16,0xb6,0x1d,0xd4, 0x09,0xc4,0x9a,0x46,0x2d,0x0e,0x75,0x07,
823 0x31,0x7b,0xed,0x45,0xcd,0x99,0x84,0x14, 0xf1,0x01,0x00,0x00,0x93,0xd5,0xa3,0xe4,
824 0x34,0x05,0xeb,0x98,0x3b,0x5f,0x2f,0x11, 0xa4,0xa5,0xc4,0xff,0xfb,0x22,0x7c,0x54
827 static const BYTE DSS_SIGN_PrivateKey[] = {
828 0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00, 0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,
829 0xf7,0x9e,0x89,0xa2,0xcd,0x0b,0x61,0xe0, 0xa3,0xe5,0x86,0x6b,0x04,0x98,0x80,0x9c,
830 0x36,0xc2,0x76,0x4e,0x22,0xd5,0x21,0xaa, 0x03,0x59,0xf4,0x95,0xb2,0x11,0x1f,0xa0,
831 0xc5,0xfc,0xbe,0x5d,0x1f,0x2e,0xf4,0x36, 0x40,0x48,0x81,0x51,0xb4,0x25,0x86,0xe0,
832 0x98,0xc8,0x4d,0xa0,0x08,0x99,0xa1,0x00, 0x45,0x1b,0x75,0x6b,0x0d,0x3e,0x7d,0x13,
833 0xd7,0x23,0x32,0x08,0xf4,0xeb,0x27,0x9e, 0xe9,0x05,0x5d,0xac,0xc8,0xd7,0x62,0x13,
834 0x43,0x2a,0x69,0x65,0xdc,0xe6,0x52,0xf9, 0x6a,0xe8,0x07,0xcf,0x3e,0xf8,0xc9,0x1d,
835 0x8e,0xdf,0x4e,0x9a,0xd1,0x48,0xf2,0xda, 0x9e,0xfa,0x92,0x5f,0x6d,0x57,0xf2,0xa4,
836 0x5f,0x60,0xce,0x92,0x7a,0x80,0x39,0x21, 0x9d,0x4d,0x3a,0x60,0x76,0x4c,0x2f,0xc0,
837 0xd3,0xf4,0x14,0x03,0x03,0x05,0xa9,0x0c, 0x57,0x72,0x4f,0x60,0x3c,0xe9,0x09,0x54,
838 0x0c,0x2a,0x56,0xda,0x30,0xb6,0x2e,0x6a, 0x96,0x7f,0x4a,0x8f,0x83,0x0a,0xb9,0x5c,
839 0xff,0x84,0xfa,0x0e,0x85,0x81,0x46,0xe9, 0x1c,0xbb,0x78,0x1d,0x78,0x25,0x00,0x8c,
840 0x78,0x56,0x68,0xe4,0x06,0x37,0xcc,0xc7, 0x22,0x27,0xee,0x0e,0xf8,0xca,0xfc,0x72,
841 0x0e,0xd6,0xe6,0x90,0x30,0x66,0x22,0xe2, 0xa2,0xbf,0x2e,0x35,0xbc,0xe7,0xd6,0x24,
842 0x6a,0x3d,0x06,0xe8,0xe2,0xbe,0x96,0xcc, 0x9a,0x08,0x06,0xb5,0x44,0x83,0xb0,0x7b,
843 0x70,0x7b,0x2d,0xc3,0x46,0x9a,0xc5,0x6b, 0xd9,0xde,0x9a,0x24,0xc9,0xea,0xf5,0x28,
844 0x69,0x8a,0x17,0xca,0xdf,0xc4,0x0e,0xa3, 0x08,0x22,0x99,0xd2,0x27,0xdc,0x9b,0x08,
845 0x54,0x4a,0xf9,0xb1,0x74,0x3a,0x9d,0xd9, 0xc2,0x82,0x21,0xf5,0x97,0x04,0x90,0x37,
846 0xda,0xd9,0xdc,0x19,0xad,0x83,0xcd,0x35, 0xb0,0x4e,0x06,0x68,0xd1,0x69,0x7e,0x73,
847 0x93,0xbe,0xa5,0x05,0xb3,0xcc,0xd2,0x51, 0x3c,0x00,0x00,0x00,0x16,0xe1,0xac,0x17,
848 0xdc,0x68,0xae,0x03,0xad,0xf7,0xb9,0xca, 0x0d,0xca,0x27,0xef,0x76,0xda,0xe5,0xcb
851 static const struct signature_test dssSign_data[] = {
852 {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign1, sizeof(dataToSign1)},
853 {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign2, sizeof(dataToSign2)},
854 {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign3, sizeof(dataToSign3)},
855 {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign1, sizeof(dataToSign1)},
856 {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign2, sizeof(dataToSign2)},
857 {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign3, sizeof(dataToSign3)}
860 static void test_signhash_array(HCRYPTPROV hProv, const struct signature_test *tests, int testLen)
862 HCRYPTHASH hHash1, hHash2;
863 HCRYPTKEY privKey = 0, pubKey = 0;
864 BYTE pubKeyBuffer[512];
865 BYTE signValue1[40], signValue2[40];
866 BYTE hashValue1[40], hashValue2[40];
867 DWORD hashLen1, hashLen2, pubKeyLen;
868 DWORD dataLen1, dataLen2;
869 BOOL result;
870 int i;
872 for (i = 0; i < testLen; i++)
874 DWORD signLen1 = tests[i].dataLen;
875 DWORD signLen2 = tests[i].dataLen;
877 /* Get a private key of array specified ALG_ID */
878 result = CryptImportKey(hProv, tests[i].privateKey, tests[i].keyLen, 0, 0, &privKey);
879 ok(result, "Failed to imported key, got %lx\n", GetLastError());
881 /* Create hash object and add data for signature 1 */
882 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
883 ok(result, "Failed to create a hash, got %lx\n", GetLastError());
885 result = CryptHashData(hHash1, tests[i].signData, signLen1, 0);
886 ok(result, "Failed to add data to hash, got %lx\n", GetLastError());
888 /* Create hash object and add data for signature 2 */
889 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
890 ok(result, "Failed to create a hash, got %lx\n", GetLastError());
892 result = CryptHashData(hHash2, tests[i].signData, signLen2, 0);
893 ok(result, "Failed to add data to hash, got %lx\n", GetLastError());
895 /* Acquire hash length and hash value */
896 dataLen1 = sizeof(DWORD);
897 result = CryptGetHashParam(hHash1, HP_HASHSIZE, (BYTE *)&hashLen1, &dataLen1, 0);
898 ok(result, "Failed to get hash length, got %lx\n", GetLastError());
900 result = CryptGetHashParam(hHash1, HP_HASHVAL, hashValue1, &hashLen1, 0);
901 ok(result, "Failed to return hash value.\n");
903 dataLen2 = sizeof(DWORD);
904 result = CryptGetHashParam(hHash2, HP_HASHSIZE, (BYTE *)&hashLen2, &dataLen2, 0);
905 ok(result, "Failed to get hash length, got %lx\n", GetLastError());
907 result = CryptGetHashParam(hHash2, HP_HASHVAL, hashValue2, &hashLen2, 0);
908 ok(result, "Failed to return hash value.\n");
910 /* Compare hashes to ensure they are the same */
911 ok(hashLen1 == hashLen2, "Hash lengths were not the same.\n");
912 ok(!memcmp(hashValue1, hashValue2, hashLen2), "Hashes were not identical.\n");
914 /* Sign hash 1 */
915 signLen1 = 0;
916 result = CryptSignHashA(hHash1, AT_SIGNATURE, NULL, 0, NULL, &signLen1);
917 ok(result, "Failed to get signature length, got %lx\n", GetLastError());
918 ok(signLen1 == 40, "Expected a 40-byte signature, got %ld\n", signLen1);
920 result = CryptSignHashA(hHash1, AT_SIGNATURE, NULL, 0, signValue1, &signLen1);
921 ok(result, "Failed to sign hash, got %lx\n", GetLastError());
923 /* Sign hash 2 */
924 signLen2 = 0;
925 result = CryptSignHashA(hHash2, AT_SIGNATURE, NULL, 0, NULL, &signLen2);
926 ok(result, "Failed to get signature length, got %lx\n", GetLastError());
927 ok(signLen2 == 40, "Expected a 40-byte signature, got %ld\n", signLen2);
929 result = CryptSignHashA(hHash2, AT_SIGNATURE, NULL, 0, signValue2, &signLen2);
930 ok(result, "Failed to sign hash2, got %lx\n", GetLastError());
932 /* Compare signatures to ensure they are both different, because every DSS signature
933 should be different even if the input hash data is identical */
934 ok(memcmp(signValue1, signValue2, signLen2), "Expected two different signatures from "
935 "the same hash input.\n");
937 result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen);
938 ok(result, "Failed to acquire public key length, got %lx\n", GetLastError());
940 /* Export the public key */
941 result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, pubKeyBuffer, &pubKeyLen);
942 ok(result, "Failed to export public key, got %lx\n", GetLastError());
944 result = CryptDestroyHash(hHash1);
945 ok(result, "Failed to destroy hash1, got %lx\n", GetLastError());
946 result = CryptDestroyHash(hHash2);
947 ok(result, "Failed to destroy hash2, got %lx\n", GetLastError());
949 /* Destroy the private key */
950 result = CryptDestroyKey(privKey);
951 ok(result, "Failed to destroy private key, got %lx\n", GetLastError());
953 /* Import the public key we obtained earlier */
954 result = CryptImportKey(hProv, pubKeyBuffer, pubKeyLen, 0, 0, &pubKey);
955 ok(result, "Failed to import public key, got %lx\n", GetLastError());
957 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
958 ok(result, "Failed to create hash, got %lx\n", GetLastError());
960 /* Hash the data to compare with the signed hash */
961 result = CryptHashData(hHash1, tests[i].signData, tests[i].dataLen, 0);
962 ok(result, "Failed to add data to hash1, got %lx\n", GetLastError());
964 /* Verify signed hash 1 */
965 result = CryptVerifySignatureA(hHash1, signValue1, sizeof(signValue1), pubKey, NULL, 0);
966 if (!result)
968 skip("skipping sign tests\n");
969 return;
971 ok(result, "Failed to verify signature, got %lx\n", GetLastError());
973 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
974 ok(result, "Failed to create hash, got %lx\n", GetLastError());
976 /* Hash the data to compare with the signed hash */
977 result = CryptHashData(hHash2, tests[i].signData, tests[i].dataLen, 0);
978 ok(result, "Failed to add data to hash2, got %lx\n", GetLastError());
980 /* Verify signed hash 2 */
981 result = CryptVerifySignatureA(hHash2, signValue2, sizeof(signValue2), pubKey, NULL, 0);
982 ok(result, "Failed to verify signature, got %lx\n", GetLastError());
984 result = CryptDestroyHash(hHash1);
985 ok(result, "Failed to destroy hash1, got %lx\n", GetLastError());
986 result = CryptDestroyHash(hHash2);
987 ok(result, "Failed to destroy hash2, got %lx\n", GetLastError());
989 /* Destroy the public key */
990 result = CryptDestroyKey(pubKey);
991 ok(result, "Failed to destroy public key, got %lx\n", GetLastError());
995 static void test_verify_signature(void)
997 HCRYPTPROV hProv = 0;
998 BOOL result;
1000 /* acquire base dss provider */
1001 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
1002 if(!result)
1004 skip("DSSENH is currently not available, skipping signature verification tests.\n");
1005 return;
1007 ok(result, "Failed to acquire CSP.\n");
1009 test_signhash_array(hProv, dssSign_data, ARRAY_SIZE(dssSign_data));
1011 result = CryptReleaseContext(hProv, 0);
1012 ok(result, "Failed to release CSP provider.\n");
1014 /* acquire diffie hellman dss provider */
1015 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, 0);
1016 ok(result, "Failed to acquire CSP.\n");
1018 test_signhash_array(hProv, dssSign_data, ARRAY_SIZE(dssSign_data));
1020 result = CryptReleaseContext(hProv, 0);
1021 ok(result, "Failed to release CSP provider.\n");
1023 /* acquire enhanced dss provider */
1024 SetLastError(0xdeadbeef);
1025 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, 0);
1026 ok(result, "Failed to acquire CSP.\n");
1028 test_signhash_array(hProv, dssSign_data, ARRAY_SIZE(dssSign_data));
1030 result = CryptReleaseContext(hProv, 0);
1031 ok(result, "Failed to release CSP provider.\n");
1033 /* acquire schannel dss provider */
1034 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, 0);
1035 ok(result, "Failed to acquire CSP.\n");
1037 test_signhash_array(hProv, dssSign_data, ARRAY_SIZE(dssSign_data));
1039 result = CryptReleaseContext(hProv, 0);
1040 ok(result, "Failed to release CSP provider.\n");
1043 struct keyExchange_test {
1044 ALG_ID algid;
1045 const BYTE *primeNum;
1046 int primeLen;
1047 const BYTE *generatorNum;
1048 int generatorLen;
1051 /* AT_KEYEXCHANGE interprets to CALG_DH_SF by the DSSENH cryptographic service provider */
1052 static const BYTE primeAT_KEYEXCHANGE[] = {
1053 0x65,0x28,0x24,0xd8,0xbe,0x3f,0x95,0x93, 0x3c,0x4d,0x1b,0x51,0xe1,0x89,0x9a,0x90,
1054 0x5e,0xa0,0x6c,0x25,0xf0,0xb5,0x93,0x98, 0xba,0x76,0x9d,0x54,0x78,0xf6,0xdc,0x04,
1055 0xe1,0xd0,0x87,0x8f,0xa0,0xe4,0x2f,0xb4, 0x09,0x78,0x24,0xbf,0xc8,0x7f,0x59,0xf4,
1056 0x07,0xee,0x07,0x20,0x1b,0x2d,0x54,0x2a, 0xb5,0xb4,0x8f,0x8c,0x33,0x73,0xec,0xaf
1059 static const BYTE generatorAT_KEYEXCHANGE[] = {
1060 0xdc,0x62,0x20,0xe7,0x36,0xa2,0xa6,0xef, 0x77,0x91,0xa8,0xa3,0x6d,0x60,0x70,0x0d,
1061 0x1d,0x79,0xb1,0xbe,0xa8,0x87,0x69,0x39, 0x29,0xaa,0x54,0x27,0x05,0xe6,0x6f,0xa5,
1062 0xde,0x82,0x00,0x5d,0x87,0x1f,0x84,0xf7, 0x40,0xec,0x6f,0x15,0x64,0x02,0x0d,0xb8,
1063 0x50,0x48,0x94,0x66,0xb2,0x7d,0xbd,0xf2, 0x66,0xf8,0x40,0x62,0x94,0xbf,0x24,0x3b
1066 static const BYTE primeCALG_DH_EPHEM[] = {
1067 0x17,0x99,0xa9,0x79,0x31,0xb9,0x05,0xdd, 0x7f,0xf0,0x02,0x11,0x4d,0x0d,0xc3,0x81,
1068 0x8b,0x41,0x50,0x41,0x5f,0x07,0xe6,0x8d, 0x02,0xf9,0xaa,0x86,0x2a,0x07,0x07,0xea,
1069 0x0a,0x75,0xed,0x96,0xa7,0x85,0xee,0xac, 0xb1,0x71,0xbd,0x57,0x48,0xbd,0x41,0x0b,
1070 0xde,0x34,0xe2,0xba,0x5b,0x55,0x64,0x77, 0x84,0xfa,0x96,0xd1,0xaf,0x79,0x49,0x9d
1073 static const BYTE generatorCALG_DH_EPHEM[] = {
1074 0xc7,0x64,0x56,0xde,0xf7,0xb4,0xd3,0xd8, 0xa2,0xd4,0x12,0x2d,0x54,0x5c,0x54,0xc8,
1075 0x04,0x11,0x88,0x14,0x6c,0x9f,0x88,0x41, 0x82,0x93,0x32,0xb1,0x82,0x84,0x5b,0x07,
1076 0x55,0x13,0x82,0x7a,0x64,0x7b,0x12,0x09, 0xe2,0xa0,0x28,0x51,0xf4,0x7a,0xd9,0x26,
1077 0x86,0x95,0x5f,0xc0,0x9a,0x25,0xc2,0x7e, 0x91,0x14,0xdd,0x3c,0x4e,0x86,0x4f,0x6f
1080 static const BYTE primeCALG_DH_SF[] = {
1081 0x85,0xb8,0xa5,0x4a,0xcf,0x2b,0x7c,0x61, 0xb2,0x06,0x93,0x8a,0x87,0x37,0x58,0xb0,
1082 0x8d,0xc7,0x2a,0xa7,0x7f,0x0d,0x74,0xf9, 0x3a,0x7e,0xbc,0xab,0x3a,0x54,0xe4,0x11,
1083 0x69,0x6f,0xcd,0xea,0xad,0x32,0x44,0x4f, 0xee,0x54,0x69,0x8c,0x9c,0x3b,0x87,0x27,
1084 0x36,0x70,0x06,0xf3,0x4e,0xde,0x7f,0x9d, 0xa6,0xf2,0xad,0x43,0x90,0xdd,0xb5,0x9b
1087 static const BYTE generatorCALG_DH_SF[] = {
1088 0xea,0xdc,0xe0,0xbb,0x60,0x26,0xc6,0xb3, 0x93,0x6f,0x61,0xe6,0x7e,0xe2,0xee,0xd6,
1089 0xdb,0x3d,0xca,0xa8,0x31,0x46,0x8f,0x5d, 0xb4,0xaa,0x83,0xd3,0x52,0x10,0xcd,0xfb,
1090 0xfd,0xfc,0x14,0x89,0x0c,0xde,0xcf,0x54, 0x1d,0x05,0x8c,0xbe,0x4a,0xe4,0x37,0xb4,
1091 0xc0,0x15,0x75,0xc5,0xa2,0xfc,0x99,0xfc, 0xad,0x63,0xcb,0x7c,0xb8,0x20,0xdc,0x2b
1094 static const struct keyExchange_test baseDSSkey_data[] = {
1095 /* Cannot exchange keys using the base DSS provider, except on WinNT4 */
1096 {AT_KEYEXCHANGE, primeAT_KEYEXCHANGE, sizeof(primeAT_KEYEXCHANGE), generatorAT_KEYEXCHANGE,
1097 sizeof(generatorAT_KEYEXCHANGE)},
1098 {CALG_DH_EPHEM, primeCALG_DH_EPHEM, sizeof(primeCALG_DH_EPHEM), generatorCALG_DH_EPHEM,
1099 sizeof(generatorCALG_DH_EPHEM)},
1100 {CALG_DH_SF, primeCALG_DH_SF, sizeof(generatorCALG_DH_SF), generatorCALG_DH_SF,
1101 sizeof(generatorCALG_DH_SF)}
1104 static const struct keyExchange_test dssDHkey_data[] = {
1105 {AT_KEYEXCHANGE, primeAT_KEYEXCHANGE, sizeof(primeAT_KEYEXCHANGE), generatorAT_KEYEXCHANGE,
1106 sizeof(generatorAT_KEYEXCHANGE)},
1107 {CALG_DH_EPHEM, primeCALG_DH_EPHEM, sizeof(primeCALG_DH_EPHEM), generatorCALG_DH_EPHEM,
1108 sizeof(generatorCALG_DH_EPHEM)},
1109 {CALG_DH_SF, primeCALG_DH_SF, sizeof(generatorCALG_DH_SF), generatorCALG_DH_SF,
1110 sizeof(generatorCALG_DH_SF)}
1113 static void test_keyExchange_baseDSS(HCRYPTPROV hProv, const struct keyExchange_test *tests, int testLen)
1115 HCRYPTKEY privKey1 = 0, privKey2 = 0;
1116 HCRYPTKEY sessionKey1 = 0, sessionKey2 = 0;
1117 const char plainText[] = "Testing shared key.";
1118 unsigned char pbData1[36];
1119 unsigned char pbData2[36];
1120 BYTE pubKeyBuffer1[512], pubKeyBuffer2[512];
1121 DWORD pubKeyLen1, pubKeyLen2, dataLen;
1122 DATA_BLOB Prime, Generator;
1123 int plainLen = sizeof(plainText), i;
1124 ALG_ID algid;
1125 BOOL result;
1127 for(i = 0; i < testLen; i++)
1129 SetLastError(0xdeadbeef);
1131 /* Create the data blobs and the prime and generator */
1132 Prime.cbData = tests[i].primeLen;
1133 Prime.pbData = (BYTE *)tests[i].primeNum;
1134 Generator.cbData = tests[i].generatorLen;
1135 Generator.pbData = (BYTE *)tests[i].generatorNum;
1137 /* Generate key exchange keys for user1 and user2 */
1138 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey1);
1139 if (!result)
1141 skip("skipping key exchange tests\n");
1142 return;
1144 ok(!result && GetLastError() == NTE_BAD_ALGID,
1145 "Expected NTE_BAD_ALGID, got %lx\n", GetLastError());
1147 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey2);
1148 ok(!result && GetLastError() == NTE_BAD_ALGID,
1149 "Expected NTE_BAD_ALGID, got %lx\n", GetLastError());
1151 /* Set the prime and generator values, which are agreed upon */
1152 result = CryptSetKeyParam(privKey1, KP_P, (BYTE *)&Prime, 0);
1153 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1154 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1156 result = CryptSetKeyParam(privKey2, KP_P, (BYTE *)&Prime, 0);
1157 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1158 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1160 result = CryptSetKeyParam(privKey1, KP_G, (BYTE *)&Generator, 0);
1161 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1162 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1164 result = CryptSetKeyParam(privKey2, KP_G, (BYTE *)&Generator, 0);
1165 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1166 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1168 /* Generate the secret value for user1 and user2 */
1169 result = CryptSetKeyParam(privKey1, KP_X, NULL, 0);
1170 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1171 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1173 result = CryptSetKeyParam(privKey2, KP_X, NULL, 0);
1174 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1175 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1177 /* Acquire required size for the public keys */
1178 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen1);
1179 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1180 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1182 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen2);
1183 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1184 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1186 /* Export public key which will be calculated into the shared key */
1187 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, pubKeyBuffer1, &pubKeyLen1);
1188 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1189 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1191 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, pubKeyBuffer2, &pubKeyLen2);
1192 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1193 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1195 /* Import the public key and convert it into a shared key */
1196 result = CryptImportKey(hProv, pubKeyBuffer2, pubKeyLen2, privKey1, 0, &sessionKey1);
1197 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) ||
1198 broken(!result && GetLastError() == NTE_BAD_DATA) || /* Vista.64 */
1199 broken(!result && GetLastError() == NTE_BAD_TYPE) || /* Win2K-W2K8, Win7.64 */
1200 broken(!result && GetLastError() == NTE_BAD_ALGID), /* W7SP164 (32 bit dssenh) */
1201 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1203 result = CryptImportKey(hProv, pubKeyBuffer1, pubKeyLen1, privKey2, 0, &sessionKey2);
1204 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) ||
1205 broken(!result && GetLastError() == NTE_BAD_DATA) || /* Win 7 */
1206 broken(!result && GetLastError() == NTE_BAD_TYPE) || /* Win2K-W2K8, Win7.64 */
1207 broken(!result && GetLastError() == NTE_BAD_ALGID), /* W7SP164 (32 bit dssenh) */
1208 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1210 /* Set the shared key parameters to matching type */
1211 algid = CALG_RC4;
1212 result = CryptSetKeyParam(sessionKey1, KP_ALGID, (BYTE *)&algid, 0);
1213 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1214 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1216 algid = CALG_RC4;
1217 result = CryptSetKeyParam(sessionKey2, KP_ALGID, (BYTE *)&algid, 0);
1218 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1219 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1221 /* Encrypt some data and verify we are getting the same output */
1222 memcpy(pbData1, plainText, plainLen);
1223 dataLen = plainLen;
1225 result = CryptEncrypt(sessionKey1, 0, TRUE, 0, pbData1, &dataLen, 36);
1226 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1227 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1229 result = CryptDecrypt(sessionKey2, 0, TRUE, 0, pbData1, &dataLen);
1230 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1231 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1233 ok(!memcmp(pbData1, (BYTE *)plainText, sizeof(plainText)), "Incorrect decrypted data.\n");
1235 memcpy(pbData2, plainText, plainLen);
1236 dataLen = plainLen;
1238 result = CryptEncrypt(sessionKey2, 0, TRUE, 0, pbData2, &dataLen, 36);
1239 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1240 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1242 result = CryptDecrypt(sessionKey1, 0, TRUE, 0, pbData2, &dataLen);
1243 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1244 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1246 ok(!memcmp(pbData1, pbData2, dataLen), "Decrypted data is not identical.\n");
1248 /* Destroy all user keys */
1249 result = CryptDestroyKey(sessionKey1);
1250 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1251 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1253 result = CryptDestroyKey(sessionKey2);
1254 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1255 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1257 result = CryptDestroyKey(privKey1);
1258 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1259 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1261 result = CryptDestroyKey(privKey2);
1262 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1263 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1267 static void test_keyExchange_dssDH(HCRYPTPROV hProv, const struct keyExchange_test *tests, int testLen)
1269 HCRYPTKEY privKey1 = 0, privKey2 = 0;
1270 HCRYPTKEY sessionKey1 = 0, sessionKey2 = 0;
1271 const char plainText[] = "Testing shared key.";
1272 unsigned char pbData1[36];
1273 unsigned char pbData2[36];
1274 BYTE pubKeyBuffer1[512], pubKeyBuffer2[512];
1275 DWORD pubKeyLen1, pubKeyLen2, dataLen;
1276 DATA_BLOB Prime, Generator;
1277 int plainLen = sizeof(plainText), i;
1278 ALG_ID algid;
1279 BOOL result;
1281 for(i = 0; i < testLen; i++)
1283 SetLastError(0xdeadbeef);
1285 /* Create the data blobs and the prime and generator */
1286 Prime.cbData = tests[i].primeLen;
1287 Prime.pbData = (BYTE *)tests[i].primeNum;
1288 Generator.cbData = tests[i].generatorLen;
1289 Generator.pbData = (BYTE *)tests[i].generatorNum;
1291 /* Generate key exchange keys for user1 and user2 */
1292 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey1);
1293 if (!result)
1295 skip("skipping key exchange tests\n");
1296 return;
1298 ok(result, "Failed to generate a key for user1, got %lx\n", GetLastError());
1300 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey2);
1301 ok(result, "Failed to generate a key for user2, got %lx\n", GetLastError());
1303 /* Set the prime and generator values, which are agreed upon */
1304 result = CryptSetKeyParam(privKey1, KP_P, (BYTE *)&Prime, 0);
1305 ok(result, "Failed to set prime for user 1's key, got %lx\n", GetLastError());
1307 result = CryptSetKeyParam(privKey2, KP_P, (BYTE *)&Prime, 0);
1308 ok(result, "Failed to set prime for user 2's key, got %lx\n", GetLastError());
1310 result = CryptSetKeyParam(privKey1, KP_G, (BYTE *)&Generator, 0);
1311 ok(result, "Failed to set generator for user 1's key, got %lx\n", GetLastError());
1313 result = CryptSetKeyParam(privKey2, KP_G, (BYTE *)&Generator, 0);
1314 ok(result, "Failed to set generator for user 2's key, got %lx\n", GetLastError());
1316 /* Generate the secret value for user1 and user2 */
1317 result = CryptSetKeyParam(privKey1, KP_X, NULL, 0);
1318 ok(result, "Failed to set secret value for user 1, got %lx\n", GetLastError());
1320 result = CryptSetKeyParam(privKey2, KP_X, NULL, 0);
1321 ok(result, "Failed to set secret value for user 2, got %lx\n", GetLastError());
1323 /* Acquire required size for the public keys */
1324 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen1);
1325 ok(result, "Failed to acquire public key length for user 1, got %lx\n", GetLastError());
1327 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen2);
1328 ok(result, "Failed to acquire public key length for user 2, got %lx\n", GetLastError());
1330 /* Export public key which will be calculated into the shared key */
1331 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, pubKeyBuffer1, &pubKeyLen1);
1332 ok(result, "Failed to export public key for user 1, got %lx\n", GetLastError());
1334 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, pubKeyBuffer2, &pubKeyLen2);
1335 ok(result, "Failed to export public key for user 2, got %lx\n", GetLastError());
1337 /* Import the public key and convert it into a shared key */
1338 result = CryptImportKey(hProv, pubKeyBuffer2, pubKeyLen2, privKey1, 0, &sessionKey1);
1339 ok(result, "Failed to import key for user 1, got %lx\n", GetLastError());
1341 result = CryptImportKey(hProv, pubKeyBuffer1, pubKeyLen1, privKey2, 0, &sessionKey2);
1342 ok(result, "Failed to import key for user 2, got %lx\n", GetLastError());
1344 /* Set the shared key parameters to matching cipher type */
1345 algid = CALG_3DES;
1346 result = CryptSetKeyParam(sessionKey1, KP_ALGID, (BYTE *)&algid, 0);
1347 ok(result, "Failed to set session key for user 1, got %lx\n", GetLastError());
1349 algid = CALG_3DES;
1350 result = CryptSetKeyParam(sessionKey2, KP_ALGID, (BYTE *)&algid, 0);
1351 ok(result, "Failed to set session key for user 2, got %lx\n", GetLastError());
1353 /* Encrypt some data and verify we are getting the correct output */
1354 memcpy(pbData1, plainText, plainLen);
1355 dataLen = plainLen;
1357 result = CryptEncrypt(sessionKey1, 0, TRUE, 0, pbData1, &dataLen, 36);
1358 ok(result, "Failed to encrypt data, got %lx.\n", GetLastError());
1360 result = CryptDecrypt(sessionKey2, 0, TRUE, 0, pbData1, &dataLen);
1361 ok(result, "Failed to decrypt data, got %lx.\n", GetLastError());
1363 ok(!memcmp(pbData1, (BYTE *)plainText, sizeof(plainText)), "Incorrect decrypted data.\n");
1365 memcpy(pbData2, plainText, plainLen);
1366 dataLen = plainLen;
1368 result = CryptEncrypt(sessionKey2, 0, TRUE, 0, pbData2, &dataLen, 36);
1369 ok(result, "Failed to encrypt data, got %lx.\n", GetLastError());
1371 result = CryptDecrypt(sessionKey1, 0, TRUE, 0, pbData2, &dataLen);
1372 ok(result, "Failed to decrypt data, got %lx.\n", GetLastError());
1374 ok(!memcmp(pbData1, pbData2, dataLen), "Decrypted data is not identical.\n");
1376 /* Destroy all user keys */
1377 result = CryptDestroyKey(sessionKey1);
1378 ok(result, "Failed to destroy session key 1, got %lx\n", GetLastError());
1380 result = CryptDestroyKey(sessionKey2);
1381 ok(result, "Failed to destroy session key 2, got %lx\n", GetLastError());
1383 result = CryptDestroyKey(privKey1);
1384 ok(result, "Failed to destroy key private key 1, got %lx\n", GetLastError());
1386 result = CryptDestroyKey(privKey2);
1387 ok(result, "Failed to destroy key private key 2, got %lx\n", GetLastError());
1391 static void test_key_exchange(void)
1393 HCRYPTPROV hProv = 0;
1394 BOOL result;
1396 /* acquire base dss provider */
1397 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
1398 if(!result)
1400 skip("DSSENH is currently not available, skipping shared key tests.\n");
1401 return;
1403 ok(result, "Failed to acquire CSP.\n");
1405 test_keyExchange_baseDSS(hProv, baseDSSkey_data, ARRAY_SIZE(baseDSSkey_data));
1407 result = CryptReleaseContext(hProv, 0);
1408 ok(result, "Failed to release CSP provider.\n");
1410 /* acquire diffie hellman dss provider */
1411 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH,
1412 CRYPT_VERIFYCONTEXT);
1413 ok(result, "Failed to acquire CSP.\n");
1415 test_keyExchange_dssDH(hProv, dssDHkey_data, ARRAY_SIZE(dssDHkey_data));
1417 result = CryptReleaseContext(hProv, 0);
1418 ok(result, "Failed to release CSP provider.\n");
1420 /* acquire enhanced dss provider */
1421 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH,
1422 CRYPT_VERIFYCONTEXT);
1423 ok(result, "Failed to acquire CSP.\n");
1425 test_keyExchange_dssDH(hProv, dssDHkey_data, ARRAY_SIZE(dssDHkey_data));
1427 result = CryptReleaseContext(hProv, 0);
1428 ok(result, "Failed to release CSP provider.\n");
1430 /* acquire schannel dss provider */
1431 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL,
1432 CRYPT_VERIFYCONTEXT);
1433 ok(result, "Failed to acquire CSP.\n");
1435 test_keyExchange_dssDH(hProv, dssDHkey_data, ARRAY_SIZE(dssDHkey_data));
1437 result = CryptReleaseContext(hProv, 0);
1438 ok(result, "Failed to release CSP provider.\n");
1441 static void test_duplicate_hash(void)
1443 static const char expected[] =
1444 {0xb9,0x7b,0xed,0xd4,0x7b,0xd8,0xa0,0xcd,0x6c,0xba,0xce,0xe9,0xb1,0x36,0xbb,0x00,0x27,0xe3,0x95,0x21};
1445 HCRYPTPROV hprov;
1446 HCRYPTHASH hhash, hhash2;
1447 BYTE buf[20];
1448 DWORD len;
1449 BOOL result;
1451 result = CryptAcquireContextA(&hprov, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
1452 ok(result, "got %08lx\n", GetLastError());
1454 result = CryptCreateHash(hprov, CALG_SHA, 0, 0, &hhash);
1455 ok(result, "got %08lx\n", GetLastError());
1457 result = CryptHashData(hhash, (const BYTE *)"winetest", sizeof("winetest"), 0);
1458 ok(result, "got %08lx\n", GetLastError());
1460 len = sizeof(buf);
1461 result = CryptGetHashParam(hhash, HP_HASHVAL, buf, &len, 0);
1462 ok(result, "got %08lx\n", GetLastError());
1463 ok(!memcmp(buf, expected, sizeof(expected)), "wrong data\n");
1465 SetLastError(0xdeadbeef);
1466 result = CryptHashData(hhash, (const BYTE *)"winetest", sizeof("winetest"), 0);
1467 ok(!result, "success\n");
1468 ok(GetLastError() == NTE_BAD_HASH_STATE, "got %08lx\n", GetLastError());
1470 result = CryptDuplicateHash(hhash, NULL, 0, &hhash2);
1471 ok(result, "got %08lx\n", GetLastError());
1473 SetLastError(0xdeadbeef);
1474 result = CryptHashData(hhash2, (const BYTE *)"winetest", sizeof("winetest"), 0);
1475 ok(!result, "success\n");
1476 ok(GetLastError() == NTE_BAD_HASH_STATE, "got %08lx\n", GetLastError());
1478 len = sizeof(buf);
1479 result = CryptGetHashParam(hhash2, HP_HASHVAL, buf, &len, 0);
1480 ok(result, "got %08lx\n", GetLastError());
1481 ok(!memcmp(buf, expected, sizeof(expected)), "wrong data\n");
1483 result = CryptDestroyHash(hhash2);
1484 ok(result, "got %08lx\n", GetLastError());
1486 result = CryptDestroyHash(hhash);
1487 ok(result, "got %08lx\n", GetLastError());
1489 result = CryptReleaseContext(hprov, 0);
1490 ok(result, "got %08lx\n", GetLastError());
1493 static void test_userkey(void)
1495 HCRYPTPROV hprov;
1496 HCRYPTKEY hkey;
1497 BOOL result;
1499 CryptAcquireContextA(&hprov, "winetest", MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_DELETEKEYSET);
1500 result = CryptAcquireContextA(&hprov, "winetest", MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
1501 ok(result, "got %08lx\n", GetLastError());
1503 SetLastError(0xdeadbeef);
1504 result = CryptGetUserKey(hprov, AT_KEYEXCHANGE, &hkey);
1505 ok(!result, "success\n");
1506 ok(GetLastError() == NTE_NO_KEY, "got %08lx\n", GetLastError());
1508 SetLastError(0xdeadbeef);
1509 result = CryptGetUserKey(hprov, AT_SIGNATURE, &hkey);
1510 ok(!result, "success\n");
1511 ok(GetLastError() == NTE_NO_KEY, "got %08lx\n", GetLastError());
1513 result = CryptGenKey(hprov, AT_SIGNATURE, 1024 << 16, &hkey);
1514 ok(result, "got %08lx\n", GetLastError());
1515 result = CryptDestroyKey(hkey);
1516 ok(result, "got %08lx\n", GetLastError());
1518 result = CryptGetUserKey(hprov, AT_SIGNATURE, &hkey);
1519 ok(result, "got %08lx\n", GetLastError());
1520 result = CryptDestroyKey(hkey);
1521 ok(result, "got %08lx\n", GetLastError());
1523 SetLastError(0xdeadbeef);
1524 result = CryptGetUserKey(hprov, AT_KEYEXCHANGE, &hkey);
1525 ok(!result, "success\n");
1526 ok(GetLastError() == NTE_NO_KEY, "got %08lx\n", GetLastError());
1528 result = CryptReleaseContext(hprov, 0);
1529 ok(result, "got %08lx\n", GetLastError());
1531 hprov = 0xdeadbeef;
1532 result = CryptAcquireContextA(&hprov, "winetest", MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_DELETEKEYSET);
1533 ok(result, "got %08lx\n", GetLastError());
1534 ok(!hprov, "got %08lx\n", (DWORD)hprov);
1537 static void test_duplicate_key(void)
1539 HCRYPTPROV hprov;
1540 HCRYPTKEY hkey, hkey2;
1541 DWORD len;
1542 BOOL result;
1543 BYTE buf[512];
1545 result = CryptAcquireContextA(&hprov, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
1546 ok(result, "got %08lx\n", GetLastError());
1548 result = CryptImportKey(hprov, DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), 0, CRYPT_EXPORTABLE, &hkey);
1549 ok(result, "got %08lx\n", GetLastError());
1551 result = CryptDuplicateKey(hkey, NULL, 0, &hkey2);
1552 ok(result, "got %08lx\n", GetLastError());
1554 len = sizeof(buf);
1555 result = CryptExportKey(hkey2, 0, PRIVATEKEYBLOB, 0, buf, &len);
1556 ok(result, "got %08lx\n", GetLastError());
1557 ok(len == sizeof(DSS_SIGN_PrivateKey), "got %lu\n", len);
1558 ok(!memcmp(buf, DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey)), "wrong data\n");
1560 result = CryptDestroyKey(hkey2);
1561 ok(result, "got %08lx\n", GetLastError());
1563 result = CryptDestroyKey(hkey);
1564 ok(result, "got %08lx\n", GetLastError());
1567 START_TEST(dssenh)
1569 test_acquire_context();
1570 test_keylength();
1571 test_hash(hash_data, ARRAY_SIZE(hash_data));
1572 test_data_encryption(encrypt_data, ARRAY_SIZE(encrypt_data));
1573 test_cipher_modes(ciphermode_data, ARRAY_SIZE(ciphermode_data));
1574 test_verify_signature();
1575 test_key_exchange();
1576 test_duplicate_hash();
1577 test_userkey();
1578 test_duplicate_key();