ddraw/tests: Add another invalid arguments test for surface QI.
[wine.git] / dlls / dssenh / tests / dssenh.c
blobccb7dcdd6d2ea8f7d9c08b2a7fef3c5ba7566b4c
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 %08x\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 %08x\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 %08x\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 todo_wine
58 ok(!result && GetLastError() == NTE_PROV_TYPE_NO_MATCH,
59 "Expected NTE_PROV_TYPE_NO_MATCH, got %08x\n", GetLastError());
61 /* cannot acquire along with MS_DEF_RSA_SIG_PROV_A, not compatible */
62 SetLastError(0xdeadbeef);
63 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_RSA_SIG_PROV_A, PROV_DSS, 0);
64 ok(!result && GetLastError() == NTE_KEYSET_NOT_DEF,
65 "Expected NTE_KEYSET_NOT_DEF, got %08x\n", GetLastError());
67 /* cannot acquire provider with 0 as Prov Type */
68 SetLastError(0xdeadbeef);
69 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, 0, 0);
70 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
71 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
73 /* test base DSS provider (PROV_DSS) */
75 result = CryptAcquireContextA(
76 &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
77 if(!result)
79 skip("DSS csp is currently not available, skipping tests.\n");
80 return;
82 ok(result, "Expected no errors.\n");
84 result = CryptReleaseContext(hProv, 0);
85 ok(result, "Expected release of the provider.\n");
87 result = CryptAcquireContextA(
88 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
89 ok(result || GetLastError() == NTE_EXISTS, "Expected no errors or NTE_EXISTS\n");
91 if (result)
93 result = CryptReleaseContext(hProv, 0);
94 ok(result, "Expected release of the provider.\n");
97 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS, 0);
98 ok(result, "Expected no errors.\n");
100 result = CryptReleaseContext(hProv, 0);
101 ok(result, "Expected release of the provider.\n");
103 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
104 ok(result, "Expected no errors.\n");
106 /* test DSS Diffie Hellman provider (PROV_DSS_DH) */
108 result = CryptAcquireContextA(
109 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
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, NULL, PROV_DSS_DH, 0);
116 ok(result, "Expected no errors.\n");
118 result = CryptReleaseContext(hProv, 0);
119 ok(result, "Expected release of the provider.\n");
121 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, 0);
122 ok(result, "Expected no errors.\n");
124 /* test DSS Enhanced provider (MS_ENH_DSS_DH_PROV_A) */
126 SetLastError(0xdeadbeef);
127 result = CryptAcquireContextA(
128 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
129 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
131 win_skip("DSSENH and Schannel provider is broken on WinNT4\n");
132 return;
134 ok(result, "Expected no errors.\n");
136 result = CryptReleaseContext(hProv, 0);
137 ok(result, "Expected release of the provider.\n");
139 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, 0);
140 ok(result, "Expected no errors.\n");
142 result = CryptReleaseContext(hProv, 0);
143 ok(result, "Expected release of the provider.\n");
145 /* test DSS Schannel provider (PROV_DH_SCHANNEL) */
147 result = CryptAcquireContextA(
148 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, CRYPT_VERIFYCONTEXT);
149 ok(result, "Expected no errors.\n");
151 result = CryptReleaseContext(hProv, 0);
152 ok(result, "Expected release of the provider.\n");
154 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DH_SCHANNEL, 0);
155 ok(result, "Expected no errors.\n");
157 result = CryptReleaseContext(hProv, 0);
158 ok(result, "Expected release of the provider.\n");
160 result = CryptAcquireContextA(
161 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, 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 /* failure tests, cannot acquire context because the key container already exists */
168 SetLastError(0xdeadbeef);
169 result = CryptAcquireContextA(
170 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
171 ok(!result && GetLastError() == NTE_EXISTS,
172 "Expected NTE_EXISTS, got %08x\n", GetLastError());
174 SetLastError(0xdeadbeef);
175 result = CryptAcquireContextA(
176 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
177 ok(!result && GetLastError() == NTE_EXISTS,
178 "Expected NTE_EXISTS, got %08x\n", GetLastError());
180 SetLastError(0xdeadbeef);
181 result = CryptAcquireContextA(
182 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, CRYPT_NEWKEYSET);
183 ok(!result && GetLastError() == NTE_EXISTS,
184 "Expected NTE_EXISTS, got %08x\n", GetLastError());
187 struct keylength_test {
188 ALG_ID algid;
189 DWORD flags;
190 BOOL expectedResult;
191 DWORD expectedError;
192 BOOL brokenResult;
193 DWORD brokenError;
194 DWORD altError;
197 static const struct keylength_test baseDSS_keylength[] = {
198 /* AT_KEYEXCHANGE is not supported by the base DSS provider */
199 {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
200 {AT_KEYEXCHANGE, 512 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
201 {AT_KEYEXCHANGE, 1024 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
202 {AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS},/* WinNT4 and Win2k */
203 /* min 512 max 1024 increment by 64 */
204 {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
205 {AT_SIGNATURE, 512 << 16, TRUE},
206 {AT_SIGNATURE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS, STATUS_INVALID_PARAMETER}, /* WinNT4 and Win2k */
207 {AT_SIGNATURE, 768 << 16, TRUE},
208 {AT_SIGNATURE, 1024 << 16, TRUE},
209 {AT_SIGNATURE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
210 /* CALG_DH_EPHEM is not supported by the base DSS provider */
211 {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
212 {CALG_DH_EPHEM, 512 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
213 {CALG_DH_EPHEM, 1024 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
214 {CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
215 /* CALG_DH_SF is not supported by the base DSS provider */
216 {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
217 {CALG_DH_SF, 512 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
218 {CALG_DH_SF, 1024 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
219 {CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
220 /* min 512 max 1024, increment by 64 */
221 {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
222 {CALG_DSS_SIGN, 512 << 16, TRUE},
223 {CALG_DSS_SIGN, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS, STATUS_INVALID_PARAMETER}, /* WinNT4 and Win2k */
224 {CALG_DSS_SIGN, 768 << 16, TRUE},
225 {CALG_DSS_SIGN, 1024 << 16, TRUE},
226 {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
229 static const struct keylength_test dssDH_keylength[] = {
230 /* min 512 max 1024, increment by 64 */
231 {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_FLAGS},
232 {AT_KEYEXCHANGE, 512 << 16, TRUE},
233 {AT_KEYEXCHANGE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
234 {AT_KEYEXCHANGE, 768 << 16, TRUE},
235 {AT_KEYEXCHANGE, 1024 << 16, TRUE},
236 {AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
237 {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
238 {AT_SIGNATURE, 512 << 16, TRUE},
239 {AT_SIGNATURE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS, STATUS_INVALID_PARAMETER}, /* WinNT4 and Win2k */
240 {AT_SIGNATURE, 768 << 16, TRUE},
241 {AT_SIGNATURE, 1024 << 16, TRUE},
242 {AT_SIGNATURE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
243 {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_FLAGS},
244 {CALG_DH_EPHEM, 512 << 16, TRUE},
245 {CALG_DH_EPHEM, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
246 {CALG_DH_EPHEM, 768 << 16, TRUE},
247 {CALG_DH_EPHEM, 1024 << 16, TRUE},
248 {CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_FLAGS},
249 {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_FLAGS},
250 {CALG_DH_SF, 512 << 16, TRUE},
251 {CALG_DH_SF, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
252 {CALG_DH_SF, 768 << 16, TRUE},
253 {CALG_DH_SF, 1024 << 16, TRUE},
254 {CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_FLAGS},
255 {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
256 {CALG_DSS_SIGN, 512 << 16, TRUE},
257 {CALG_DSS_SIGN, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS, STATUS_INVALID_PARAMETER}, /* WinNT4 and Win2k */
258 {CALG_DSS_SIGN, 768 << 16, TRUE},
259 {CALG_DSS_SIGN, 1024 << 16, TRUE},
260 {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
263 static const struct keylength_test dssENH_keylength[] = {
264 /* min 512 max 1024 (AT_KEYEXCHANGE max 4096), increment by 64*/
265 {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_FLAGS},
266 {AT_KEYEXCHANGE, 512 << 16, TRUE},
267 {AT_KEYEXCHANGE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
268 {AT_KEYEXCHANGE, 768 << 16, TRUE},
269 {AT_KEYEXCHANGE, 1024 << 16, TRUE},
270 {AT_KEYEXCHANGE, 1088 << 16, TRUE},
271 {AT_KEYEXCHANGE, 2048 << 16, TRUE},
272 /* Keylength too large - test bot timeout.
273 {AT_KEYEXCHANGE, 3072 << 16, TRUE},
274 {AT_KEYEXCHANGE, 4096 << 16, TRUE}, */
275 {AT_KEYEXCHANGE, 4160 << 16, FALSE, NTE_BAD_FLAGS},
276 {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
277 {AT_SIGNATURE, 512 << 16, TRUE},
278 {AT_SIGNATURE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS, STATUS_INVALID_PARAMETER}, /* WinNT4 and Win2k */
279 {AT_SIGNATURE, 768 << 16, TRUE},
280 {AT_SIGNATURE, 1024 << 16, TRUE},
281 {AT_SIGNATURE, 1032 << 16, FALSE, NTE_BAD_FLAGS},
282 {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_FLAGS},
283 {CALG_DH_EPHEM, 512 << 16, TRUE},
284 {CALG_DH_EPHEM, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
285 {CALG_DH_EPHEM, 768 << 16, TRUE},
286 {CALG_DH_EPHEM, 1024 << 16, TRUE},
287 {CALG_DH_EPHEM, 1040 << 16, FALSE, NTE_BAD_FLAGS},
288 {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_FLAGS},
289 {CALG_DH_SF, 512 << 16, TRUE},
290 {CALG_DH_SF, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
291 {CALG_DH_SF, 768 << 16, TRUE},
292 {CALG_DH_SF, 1024 << 16, TRUE},
293 {CALG_DH_SF, 1032 << 16, FALSE, NTE_BAD_FLAGS},
294 {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
295 {CALG_DSS_SIGN, 512 << 16, TRUE},
296 {CALG_DSS_SIGN, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS, STATUS_INVALID_PARAMETER}, /* WinNT4 and Win2k */
297 {CALG_DSS_SIGN, 768 << 16, TRUE},
298 {CALG_DSS_SIGN, 1024 << 16, TRUE},
299 {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
302 static void test_keylength_array(HCRYPTPROV hProv,const struct keylength_test *tests, int testLen)
304 HCRYPTKEY key;
305 BOOL result;
306 int i;
308 for (i = 0; i < testLen; i++)
310 SetLastError(0xdeadbeef);
311 result = CryptGenKey(hProv, tests[i].algid, tests[i].flags, &key);
313 /* success */
314 if(tests[i].expectedResult)
316 ok(result, "%d: Expected a key, got %08x\n", i, GetLastError());
317 result = CryptDestroyKey(key);
318 ok(result, "Expected no errors.\n");
320 else
321 { /* error but success on older system */
322 if(tests[i].brokenResult)
323 ok((!result && GetLastError() == tests[i].expectedError) ||
324 broken(result), "%d: Didn't really expect a key, got %x, %d\n",
325 i, GetLastError(), result);
326 else
328 /* error */
329 if(!tests[i].brokenError)
330 ok(!result && GetLastError() == tests[i].expectedError,
331 "%d: Expected an error, got %x, %d.\n", i, GetLastError(), result);
333 /* error but different error on older system */
334 else
335 ok(!result && (GetLastError() == tests[i].expectedError ||
336 GetLastError() == tests[i].altError ||
337 broken(GetLastError() == tests[i].brokenError) ),
338 "%d: Expected an error, got %x, %d.\n", i, GetLastError(), result);
344 #define TESTLEN(x) (sizeof(x) / sizeof((x)[0]))
346 static void test_keylength(void)
348 HCRYPTPROV hProv = 0;
349 BOOL result;
351 /* acquire base dss provider */
352 result = CryptAcquireContextA(
353 &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
354 if(!result)
356 skip("DSSENH is currently not available, skipping key length tests.\n");
357 return;
359 ok(result, "Expected no errors.\n");
361 /* perform keylength tests */
362 test_keylength_array(hProv, baseDSS_keylength, TESTLEN(baseDSS_keylength));
364 result = CryptReleaseContext(hProv, 0);
365 ok(result, "Expected release of CSP provider.\n");
367 /* acquire diffie hellman dss provider */
368 result = CryptAcquireContextA(
369 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
370 ok(result, "Expected no errors.\n");
372 /* perform keylength tests */
373 test_keylength_array(hProv, dssDH_keylength, TESTLEN(dssDH_keylength));
375 result = CryptReleaseContext(hProv, 0);
376 ok(result, "Expected release of CSP provider.\n");
378 /* acquire enhanced dss provider */
379 SetLastError(0xdeadbeef);
380 result = CryptAcquireContextA(
381 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
382 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
384 win_skip("DSSENH and Schannel provider is broken on WinNT4\n");
385 return;
387 ok(result, "Expected no errors.\n");
389 /* perform keylength tests */
390 test_keylength_array(hProv, dssENH_keylength, TESTLEN(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, TESTLEN(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 %d hash len, got %d.Error: %x\n",
473 tests[i].hashLen, hashLen, GetLastError());
475 result = CryptGetHashParam(hHash, HP_HASHVAL, hashValue, &hashLen, 0);
476 ok(result, "Expected hash value return.\n");
478 ok(!memcmp(hashValue, tests[i].hash, tests[i].hashLen), "Incorrect hash output.\n");
480 result = CryptHashData(hHash, data, dataLen, 0);
481 ok(!result, "Should not be able to add to hash.\n");
483 result = CryptDestroyHash(hHash);
484 ok(result, "Expected destruction of hash.\n");
486 result = CryptReleaseContext(hProv, 0);
487 ok(result, "Expected release of the DSS Enhanced provider.\n");
490 struct encrypt_test {
491 ALG_ID algid;
492 DWORD keyLength;
493 const char *plain;
494 DWORD plainLen;
495 const BYTE *decrypted;
496 const BYTE *encrypted;
499 static const char dataToEncrypt1[] = "Great performance with Wine.";
500 static const char dataToEncrypt2[] = "Wine implements Windows API";
501 static const char dataToEncrypt3[] = "";
503 static const BYTE encrypted3DES_1[] = {
504 0x6c,0x60,0x19,0x41,0x27,0xc1,0x16,0x69, 0x6f,0x96,0x0c,0x2e,0xa4,0x5f,0xf5,0x6a,
505 0xed,0x4b,0xec,0xd4,0x92,0x0c,0xe2,0x34, 0xe1,0x4a,0xb5,0xe2,0x05,0x43,0xfe,0x17
507 static const BYTE encrypted3DES_2[] = {
508 0x17,0xeb,0x80,0xde,0xac,0x4d,0x9e,0xd0, 0xa9,0xae,0x74,0xb5,0x86,0x1a,0xea,0xb4,
509 0x96,0x27,0x5d,0x75,0x4f,0xdd,0x87,0x60, 0xfc,0xaf,0xa1,0x82,0x83,0x09,0xf1,0xca
511 static const BYTE encrypted3DES_3[] = {0xaf, 0x36, 0xc0, 0x3d, 0x78, 0x64, 0xc4, 0x4a};
513 static const BYTE encrypted3DES112_1[] = {
514 0xb3,0xf8,0x4b,0x08,0xd6,0x23,0xcb,0xca, 0x43,0x26,0xd9,0x9f,0x6b,0x99,0x09,0xe9,
515 0x8c,0x4c,0x7d,0xef,0x49,0xda,0x0b,0x44, 0xcc,0x8d,0x06,0x6b,0xed,0xb7,0xf1,0x67
517 static const BYTE encrypted3DES112_2[] = {
518 0xdc,0xcf,0x93,0x11,0x7a,0xe4,0xcd,0x3f, 0x11,0xd8,0xe0,0x1e,0xe0,0x8d,0x9c,0xba,
519 0x97,0x5d,0x74,0x4d,0x83,0x03,0x5c,0xf2, 0x01,0xaf,0xed,0x7a,0x87,0x8f,0x88,0x8b
521 static const BYTE encrypted3DES112_3[] = {0x04, 0xb3, 0x9c, 0x59, 0x48, 0xc7, 0x2f, 0xd1};
523 static const BYTE encryptedDES_1[] = {
524 0x3d,0xdc,0x54,0xaf,0x66,0x72,0x4e,0xef, 0x9d,0x35,0x02,0xc2,0x1a,0xf4,0x1f,0x01,
525 0xb1,0xaf,0x13,0xd9,0xbe,0x7b,0xd4,0xf3, 0xf5,0x9d,0x2a,0xd8,0x32,0x90,0xe9,0x0b
527 static const BYTE encryptedDES_2[] = {
528 0xa8,0x05,0xd7,0xe9,0x61,0xf4,0x6c,0xce, 0x95,0x2b,0x52,0x08,0x25,0x03,0x30,0xac,
529 0xd7,0xe7,0xd3,0x07,0xb2,0x68,0x63,0x7b, 0xe3,0xab,0x26,0x1e,0x5c,0xec,0x42,0x4f
531 static const BYTE encryptedDES_3[] = {0x35, 0x02, 0xbb, 0x7c, 0x43, 0x5b, 0xf5, 0x59};
533 static const BYTE encryptedRC2_1[] = {
534 0x9e,0xcb,0xa2,0x27,0xc2,0xec,0x10,0xe0, 0x94,0xb3,0xc3,0x9d,0x7d,0xe2,0x12,0xe4,
535 0xb0,0xde,0xd9,0x46,0xca,0x1f,0xa6,0xfa, 0xa4,0x79,0x08,0x59,0xa6,0x00,0x62,0x16
537 static const BYTE encryptedRC2_2[] = {
538 0x29,0x06,0xfd,0xa1,0xe0,0x88,0x89,0xb0, 0x4d,0x7f,0x96,0x9d,0x2c,0x44,0xa1,0xd2,
539 0xbe,0xc6,0xaf,0x10,0xb8,0x86,0x68,0x1b, 0x1d,0x9f,0x3c,0xc4,0x12,0x02,0xbc,0x73
541 static const BYTE encryptedRC2_3[] = {0x26,0x40,0x73,0xfe,0x13,0xbb,0x32,0xa8};
543 static const BYTE encryptedRC4_1[] = {
544 0x5a,0x48,0xeb,0x16,0x96,0x23,0x16,0xb7, 0xbb,0x36,0xe8,0x43,0x88,0x74,0xb1,0x9d,
545 0x96,0xf0,0x84,0x0f,0x5a,0x56,0xf9,0x62, 0xae,0xb5,0x4a,0xce,0x52
547 static const BYTE encryptedRC4_2[] = {
548 0x4a,0x53,0xe0,0x12,0xc2,0x6a,0x0b,0xa2, 0xa5,0x35,0xea,0x54,0x8b,0x61,0xac,0xde,
549 0xa4,0xb9,0x9d,0x02,0x41,0x49,0xaa,0x15, 0x86,0x8b,0x66,0xe0
551 static const BYTE encryptedRC4_3[] = {0x1d};
553 static const struct encrypt_test encrypt_data[] = {
554 {CALG_3DES, 168 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
555 encrypted3DES_1},
556 {CALG_3DES, 168 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
557 encrypted3DES_2},
558 {CALG_3DES, 168 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
559 encrypted3DES_3},
560 {CALG_3DES_112, 112 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
561 encrypted3DES112_1},
562 {CALG_3DES_112, 112 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
563 encrypted3DES112_2},
564 {CALG_3DES_112, 112 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
565 encrypted3DES112_3},
566 {CALG_DES, 56 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
567 encryptedDES_1},
568 {CALG_DES, 56 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
569 encryptedDES_2},
570 {CALG_DES, 56 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
571 encryptedDES_3},
572 /* CALG_RC2 key unexpected results under Win2K when default key length is used, here we use
573 minimum length because Win2K's DSSENH provider has a different default key length compared
574 to the younger operating systems, though there is no default key len issue with CALG_RC4 */
575 {CALG_RC2, 40 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
576 encryptedRC2_1},
577 {CALG_RC2, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
578 encryptedRC2_2},
579 {CALG_RC2, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
580 encryptedRC2_3},
581 {CALG_RC4, 40 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
582 encryptedRC4_1},
583 {CALG_RC4, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
584 encryptedRC4_2},
585 {CALG_RC4, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
586 encryptedRC4_3}
589 static void test_data_encryption(const struct encrypt_test *tests, int testLen)
590 { /* Here we test the same encryption ciphers as the RSAENH cryptographic service provider */
591 HCRYPTPROV hProv = 0;
592 HCRYPTKEY pKey = 0;
593 HCRYPTHASH hHash;
594 const char dataToHash[] = "I love working with Wine";
595 unsigned char pbData[36];
596 DWORD dataLen;
597 BOOL result;
598 int i;
600 /* acquire dss enhanced provider */
601 SetLastError(0xdeadbeef);
602 result = CryptAcquireContextA(
603 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
604 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
606 skip("DSSENH is currently not available, skipping encryption tests.\n");
607 return;
609 ok(result, "Expected no errors.\n");
611 /* testing various encryption algorithms */
612 for(i = 0; i < testLen; i++)
614 memcpy(pbData, tests[i].plain, tests[i].plainLen);
615 dataLen = tests[i].plainLen;
617 SetLastError(0xdeadbeef);
618 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
619 ok(result, "Expected creation of a MD5 hash for key derivation.\n");
621 result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
622 ok(result, "Expected data to be added to hash for key derivation.\n");
624 /* Derive key */
625 result = CryptDeriveKey(hProv, tests[i].algid, hHash, tests[i].keyLength, &pKey);
626 ok(result, "Expected a derived key.\n");
628 result = CryptDestroyHash(hHash);
629 ok(result, "Expected destruction of hash after deriving key.\n");
631 /* testing CryptEncrypt with ALGID from array */
632 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
633 ok(result, "Expected data encryption.\n");
635 /* Verify we have received expected encrypted data */
636 ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
638 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
639 ok(result, "Expected data decryption.\n");
641 /* Verify we have received expected decrypted data */
642 ok(!memcmp(pbData, tests[i].decrypted, dataLen) ||
643 broken(tests[i].algid == CALG_RC4), "Incorrect decrypted data.\n");
645 result = CryptDestroyKey(pKey);
646 ok(result, "Expected no DestroyKey errors.\n");
648 result = CryptReleaseContext(hProv, 0);
649 ok(result, "Expected release of the provider\n");
652 struct ciphermode_test {
653 DWORD cipherMode;
654 BOOL expectedResult;
655 DWORD expectedError;
656 const BYTE *encrypted;
659 static const BYTE encryptedCFB[] = {
660 0x51,0x15,0x77,0xab,0x62,0x1f,0x7d,0xcb, 0x35,0x1e,0xd8,0xd3,0x2a,0x00,0xf0,0x94,
661 0x7c,0xa5,0x28,0xda,0xb8,0x81,0x15,0x99, 0xd1,0xd5,0x06,0x1d,0xd3,0x46,0x7e,0xca
663 static const BYTE encryptedCBC[] = {
664 0x8f,0x7b,0x56,0xeb,0xad,0x4d,0x76,0xc2, 0xd5,0x1d,0xf0,0x60,0x9d,0xde,0x96,0xe8,
665 0xb7,0x7b,0xeb,0x4b,0xee,0x3f,0xae,0x05, 0x20,0xf5,0xe0,0x75,0xa0,0x1d,0xf9,0x39
667 static const BYTE encryptedECB[] = {
668 0x8f,0x7b,0x56,0xeb,0xad,0x4d,0x76,0xc2, 0x8b,0xe0,0x4e,0xe4,0x98,0x4f,0xb8,0x3b,
669 0xf3,0xeb,0x6f,0x0a,0x57,0x91,0xdd,0xc7, 0x34,0x5d,0x4c,0xa3,0x7e,0x97,0xbf,0xee
672 static const struct ciphermode_test ciphermode_data[] = {
673 {CRYPT_MODE_CFB, TRUE, 0xdeadbeef, encryptedCFB}, /* Testing cipher block chaining */
674 {CRYPT_MODE_CBC, TRUE, 0xdeadbeef, encryptedCBC}, /* Testing cipher feedback */
675 {CRYPT_MODE_ECB, TRUE, 0xdeadbeef, encryptedECB}, /* Testing electronic codebook */
676 {CRYPT_MODE_OFB, FALSE, NTE_BAD_DATA}/* DSSENH does not support Output Feedback cipher mode */
679 static void test_cipher_modes(const struct ciphermode_test *tests, int testLen)
681 HCRYPTPROV hProv = 0;
682 HCRYPTKEY pKey = 0;
683 HCRYPTHASH hHash;
684 const char plainText[] = "Testing block cipher modes.";
685 const char dataToHash[] = "GSOC is awesome!";
686 unsigned char pbData[36];
687 int plainLen = sizeof(plainText), i;
688 DWORD mode, dataLen;
689 BOOL result;
691 /* acquire dss enhanced provider */
692 SetLastError(0xdeadbeef);
693 result = CryptAcquireContextA(
694 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
695 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
697 skip("DSSENH is currently not available, skipping block cipher mode tests.\n");
698 return;
700 ok(result, "Expected no errors.\n");
702 SetLastError(0xdeadbeef);
703 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
704 ok(result, "Expected creation of a MD5 hash for key derivation.\n");
706 result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
707 ok(result, "Expected data to be added to hash for key derivation.\n");
709 /* Derive a CALG_RC2 key, but could be any other encryption cipher */
710 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &pKey);
711 ok(result, "Expected a derived key.\n");
713 result = CryptDestroyHash(hHash);
714 ok(result, "Expected destruction of hash after deriving key.\n");
716 /* the default algorithm is CBC, test that without setting a mode */
717 mode = 0xdeadbeef;
718 dataLen = sizeof(mode);
719 result = CryptGetKeyParam(pKey, KP_MODE, (BYTE*)&mode, &dataLen, 0);
720 ok(result, "Expected getting of KP_MODE, got %x.\n", GetLastError());
721 ok(mode == CRYPT_MODE_CBC, "Default mode should be CBC\n");
723 memcpy(pbData, plainText, plainLen);
724 dataLen = plainLen;
725 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
726 ok(result, "Expected data encryption, got %x.\n", GetLastError());
728 /* Verify we have the correct encrypted data */
729 ok(!memcmp(pbData, tests[1].encrypted, dataLen), "Incorrect encrypted data.\n");
731 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
732 ok(result, "Expected data decryption, got %x.\n", GetLastError());
734 /* Verify we have the correct decrypted data */
735 ok(!memcmp(pbData, (BYTE *)plainText, dataLen), "Incorrect decrypted data.\n");
737 /* test block cipher modes */
738 for(i = 0; i < testLen; i++)
740 SetLastError(0xdeadbeef);
741 dataLen = plainLen;
742 mode = tests[i].cipherMode;
743 memcpy(pbData, plainText, plainLen);
745 result = CryptSetKeyParam(pKey, KP_MODE, (BYTE*)&mode, 0);
746 if(tests[i].expectedResult)
748 ok(result, "Expected setting of KP_MODE, got %x.\n", GetLastError());
750 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
751 ok(result, "Expected data encryption, got %x.\n", GetLastError());
753 /* Verify we have the correct encrypted data */
754 ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
756 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
757 ok(result, "Expected data decryption, got %x.\n", GetLastError());
759 /* Verify we have the correct decrypted data */
760 ok(!memcmp(pbData, (BYTE *)plainText, dataLen), "Incorrect decrypted data.\n");
762 else
763 { /* Expected error */
764 ok(!result && GetLastError() == tests[i].expectedError, "Expected %d, got %x.\n",
765 tests[i].expectedError, GetLastError());
768 result = CryptDestroyKey(pKey);
769 ok(result, "Expected no DestroyKey errors.\n");
771 result = CryptReleaseContext(hProv, 0);
772 ok(result, "Expected release of the provider.\n");
775 struct signature_test {
776 const BYTE *privateKey;
777 DWORD keyLen;
778 BYTE* signData;
779 DWORD dataLen;
782 static const char dataToSign1[] = "Put your hands up for Cryptography :)";
783 static const char dataToSign2[] = "With DSSENH implemented, applications requiring it will now work.";
784 static const char dataToSign3[] = "";
786 static const BYTE AT_SIGNATURE_PrivateKey[] = {
787 0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00, 0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,
788 0x01,0xd1,0xfc,0x7a,0x70,0x53,0xb2,0x48, 0x70,0x23,0x19,0x1f,0x3c,0xe1,0x26,0x14,
789 0x7e,0x9f,0x0f,0x7f,0x33,0x5e,0x2b,0xf7, 0xca,0x01,0x74,0x8c,0xb4,0xfd,0xf6,0x44,
790 0x95,0x35,0x56,0xaa,0x4d,0x62,0x48,0xe2, 0xd1,0xa2,0x7e,0x6e,0xeb,0xd6,0xcc,0x7c,
791 0xe8,0xfd,0x21,0x9a,0xa2,0xfd,0x7a,0x9d, 0x1a,0x38,0x69,0x87,0x39,0x5a,0x91,0xc0,
792 0x52,0x2b,0x9f,0x2a,0x54,0x78,0x37,0x82, 0x9a,0x70,0x57,0xab,0xec,0x93,0x8e,0xac,
793 0x73,0x04,0xe8,0x53,0x72,0x72,0x32,0xc6, 0xcb,0xef,0x47,0x98,0x3c,0x56,0x49,0x62,
794 0xcb,0xbb,0xe7,0x34,0x84,0xa6,0x72,0x3a, 0xbe,0x26,0x46,0x86,0xca,0xcb,0x35,0x62,
795 0x4f,0x19,0x18,0x0b,0xb0,0x78,0xae,0xd5, 0x42,0xdf,0x26,0xdb,0x85,0x63,0x77,0x85,
796 0x01,0x3b,0x32,0xbe,0x5c,0xf8,0x05,0xc8, 0xde,0x17,0x7f,0xb9,0x03,0x82,0xfa,0xf1,
797 0x9e,0x32,0x73,0xfa,0x8d,0xea,0xa3,0x30, 0x48,0xe2,0xdf,0x5a,0xcb,0x83,0x3d,0xff,
798 0x56,0xe9,0xc0,0x94,0xf8,0x6d,0xb3,0xaf, 0x4a,0x97,0xb9,0x43,0x0e,0xd4,0x28,0x98,
799 0x57,0x2e,0x3a,0xca,0xde,0x6f,0x45,0x0d, 0xfb,0x58,0xec,0x78,0x34,0x2e,0x46,0x4d,
800 0xfe,0x98,0x02,0xbb,0xef,0x07,0x1a,0x13, 0xb6,0xc2,0x2c,0x06,0xd9,0x0c,0xc4,0xb0,
801 0x4c,0x3a,0xfc,0x01,0x63,0xb5,0x5a,0x5d, 0x2d,0x9c,0x47,0x04,0x67,0x51,0xf2,0x52,
802 0xf5,0x82,0x36,0xeb,0x6e,0x66,0x58,0x4c, 0x10,0x2c,0x29,0x72,0x4a,0x6f,0x6b,0x6c,
803 0xe0,0x93,0x31,0x42,0xf6,0xda,0xfa,0x5b, 0x22,0x43,0x9b,0x1a,0x98,0x71,0xe7,0x41,
804 0x74,0xe9,0x12,0xa4,0x1f,0x27,0x0a,0x63, 0x94,0x49,0xd7,0xad,0xa5,0xc4,0x5c,0xc3,
805 0xc9,0x70,0xb3,0x7b,0x16,0xb6,0x1d,0xd4, 0x09,0xc4,0x9a,0x46,0x2d,0x0e,0x75,0x07,
806 0x31,0x7b,0xed,0x45,0xcd,0x99,0x84,0x14, 0xf1,0x01,0x00,0x00,0x93,0xd5,0xa3,0xe4,
807 0x34,0x05,0xeb,0x98,0x3b,0x5f,0x2f,0x11, 0xa4,0xa5,0xc4,0xff,0xfb,0x22,0x7c,0x54
810 static const BYTE DSS_SIGN_PrivateKey[] = {
811 0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00, 0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,
812 0xf7,0x9e,0x89,0xa2,0xcd,0x0b,0x61,0xe0, 0xa3,0xe5,0x86,0x6b,0x04,0x98,0x80,0x9c,
813 0x36,0xc2,0x76,0x4e,0x22,0xd5,0x21,0xaa, 0x03,0x59,0xf4,0x95,0xb2,0x11,0x1f,0xa0,
814 0xc5,0xfc,0xbe,0x5d,0x1f,0x2e,0xf4,0x36, 0x40,0x48,0x81,0x51,0xb4,0x25,0x86,0xe0,
815 0x98,0xc8,0x4d,0xa0,0x08,0x99,0xa1,0x00, 0x45,0x1b,0x75,0x6b,0x0d,0x3e,0x7d,0x13,
816 0xd7,0x23,0x32,0x08,0xf4,0xeb,0x27,0x9e, 0xe9,0x05,0x5d,0xac,0xc8,0xd7,0x62,0x13,
817 0x43,0x2a,0x69,0x65,0xdc,0xe6,0x52,0xf9, 0x6a,0xe8,0x07,0xcf,0x3e,0xf8,0xc9,0x1d,
818 0x8e,0xdf,0x4e,0x9a,0xd1,0x48,0xf2,0xda, 0x9e,0xfa,0x92,0x5f,0x6d,0x57,0xf2,0xa4,
819 0x5f,0x60,0xce,0x92,0x7a,0x80,0x39,0x21, 0x9d,0x4d,0x3a,0x60,0x76,0x4c,0x2f,0xc0,
820 0xd3,0xf4,0x14,0x03,0x03,0x05,0xa9,0x0c, 0x57,0x72,0x4f,0x60,0x3c,0xe9,0x09,0x54,
821 0x0c,0x2a,0x56,0xda,0x30,0xb6,0x2e,0x6a, 0x96,0x7f,0x4a,0x8f,0x83,0x0a,0xb9,0x5c,
822 0xff,0x84,0xfa,0x0e,0x85,0x81,0x46,0xe9, 0x1c,0xbb,0x78,0x1d,0x78,0x25,0x00,0x8c,
823 0x78,0x56,0x68,0xe4,0x06,0x37,0xcc,0xc7, 0x22,0x27,0xee,0x0e,0xf8,0xca,0xfc,0x72,
824 0x0e,0xd6,0xe6,0x90,0x30,0x66,0x22,0xe2, 0xa2,0xbf,0x2e,0x35,0xbc,0xe7,0xd6,0x24,
825 0x6a,0x3d,0x06,0xe8,0xe2,0xbe,0x96,0xcc, 0x9a,0x08,0x06,0xb5,0x44,0x83,0xb0,0x7b,
826 0x70,0x7b,0x2d,0xc3,0x46,0x9a,0xc5,0x6b, 0xd9,0xde,0x9a,0x24,0xc9,0xea,0xf5,0x28,
827 0x69,0x8a,0x17,0xca,0xdf,0xc4,0x0e,0xa3, 0x08,0x22,0x99,0xd2,0x27,0xdc,0x9b,0x08,
828 0x54,0x4a,0xf9,0xb1,0x74,0x3a,0x9d,0xd9, 0xc2,0x82,0x21,0xf5,0x97,0x04,0x90,0x37,
829 0xda,0xd9,0xdc,0x19,0xad,0x83,0xcd,0x35, 0xb0,0x4e,0x06,0x68,0xd1,0x69,0x7e,0x73,
830 0x93,0xbe,0xa5,0x05,0xb3,0xcc,0xd2,0x51, 0x3c,0x00,0x00,0x00,0x16,0xe1,0xac,0x17,
831 0xdc,0x68,0xae,0x03,0xad,0xf7,0xb9,0xca, 0x0d,0xca,0x27,0xef,0x76,0xda,0xe5,0xcb
834 static const struct signature_test dssSign_data[] = {
835 {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign1, sizeof(dataToSign1)},
836 {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign2, sizeof(dataToSign2)},
837 {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign3, sizeof(dataToSign3)},
838 {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign1, sizeof(dataToSign1)},
839 {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign2, sizeof(dataToSign2)},
840 {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign3, sizeof(dataToSign3)}
843 static void test_signhash_array(HCRYPTPROV hProv, const struct signature_test *tests, int testLen)
845 HCRYPTHASH hHash1, hHash2;
846 HCRYPTKEY privKey = 0, pubKey = 0;
847 BYTE pubKeyBuffer[512];
848 BYTE signValue1[40], signValue2[40];
849 BYTE hashValue1[40], hashValue2[40];
850 DWORD hashLen1, hashLen2, pubKeyLen;
851 DWORD dataLen1, dataLen2;
852 BOOL result;
853 int i;
855 for (i = 0; i < testLen; i++)
857 DWORD signLen1 = tests[i].dataLen;
858 DWORD signLen2 = tests[i].dataLen;
860 /* Get a private key of array specified ALG_ID */
861 result = CryptImportKey(hProv, tests[i].privateKey, tests[i].keyLen, 0, 0, &privKey);
862 ok(result, "Failed to imported key, got %x\n", GetLastError());
864 /* Create hash object and add data for signature 1 */
865 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
866 ok(result, "Failed to create a hash, got %x\n", GetLastError());
868 result = CryptHashData(hHash1, tests[i].signData, signLen1, 0);
869 ok(result, "Failed to add data to hash, got %x\n", GetLastError());
871 /* Create hash object and add data for signature 2 */
872 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
873 ok(result, "Failed to create a hash, got %x\n", GetLastError());
875 result = CryptHashData(hHash2, tests[i].signData, signLen2, 0);
876 ok(result, "Failed to add data to hash, got %x\n", GetLastError());
878 /* Acquire hash length and hash value */
879 dataLen1 = sizeof(DWORD);
880 result = CryptGetHashParam(hHash1, HP_HASHSIZE, (BYTE *)&hashLen1, &dataLen1, 0);
881 ok(result, "Failed to get hash length, got %x\n", GetLastError());
883 result = CryptGetHashParam(hHash1, HP_HASHVAL, hashValue1, &hashLen1, 0);
884 ok(result, "Failed to return hash value.\n");
886 dataLen2 = sizeof(DWORD);
887 result = CryptGetHashParam(hHash2, HP_HASHSIZE, (BYTE *)&hashLen2, &dataLen2, 0);
888 ok(result, "Failed to get hash length, got %x\n", GetLastError());
890 result = CryptGetHashParam(hHash2, HP_HASHVAL, hashValue2, &hashLen2, 0);
891 ok(result, "Failed to return hash value.\n");
893 /* Compare hashes to ensure they are the same */
894 ok(hashLen1 == hashLen2, "Hash lengths were not the same.\n");
895 ok(!memcmp(hashValue1, hashValue2, hashLen2), "Hashes were not identical.\n");
897 /* Sign hash 1 */
898 result = CryptSignHashA(hHash1, AT_SIGNATURE, NULL, 0, NULL, &signLen1);
899 ok(result, "Failed to get signature length, got %x\n", GetLastError());
900 ok(signLen1 == 40, "Expected a 40-byte signature, got %d\n", signLen1);
902 result = CryptSignHashA(hHash1, AT_SIGNATURE, NULL, 0, signValue1, &signLen1);
903 ok(result, "Failed to sign hash, got %x\n", GetLastError());
905 /* Sign hash 2 */
906 result = CryptSignHashA(hHash2, AT_SIGNATURE, NULL, 0, NULL, &signLen2);
907 ok(result, "Failed to get signature length, got %x\n", GetLastError());
908 ok(signLen2 == 40, "Expected a 40-byte signature, got %d\n", signLen2);
910 result = CryptSignHashA(hHash2, AT_SIGNATURE, NULL, 0, signValue2, &signLen2);
911 ok(result, "Failed to sign hash2, got %x\n", GetLastError());
913 /* Compare signatures to ensure they are both different, because every DSS signature
914 should be different even if the input hash data is identical */
915 ok(memcmp(signValue1, signValue2, signLen2), "Expected two different signatures from "
916 "the same hash input.\n");
918 result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen);
919 ok(result, "Failed to acquire public key length, got %x\n", GetLastError());
921 /* Export the public key */
922 result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, pubKeyBuffer, &pubKeyLen);
923 ok(result, "Failed to export public key, got %x\n", GetLastError());
925 result = CryptDestroyHash(hHash1);
926 ok(result, "Failed to destroy hash1, got %x\n", GetLastError());
927 result = CryptDestroyHash(hHash2);
928 ok(result, "Failed to destroy hash2, got %x\n", GetLastError());
930 /* Destroy the private key */
931 result = CryptDestroyKey(privKey);
932 ok(result, "Failed to destroy private key, got %x\n", GetLastError());
934 /* Import the public key we obtained earlier */
935 result = CryptImportKey(hProv, pubKeyBuffer, pubKeyLen, 0, 0, &pubKey);
936 ok(result, "Failed to import public key, got %x\n", GetLastError());
938 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
939 ok(result, "Failed to create hash, got %x\n", GetLastError());
941 /* Hash the data to compare with the signed hash */
942 result = CryptHashData(hHash1, tests[i].signData, tests[i].dataLen, 0);
943 ok(result, "Failed to add data to hash1, got %x\n", GetLastError());
945 /* Verify signed hash 1 */
946 result = CryptVerifySignatureA(hHash1, signValue1, sizeof(signValue1), pubKey, NULL, 0);
947 ok(result, "Failed to verify signature, got %x\n", GetLastError());
949 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
950 ok(result, "Failed to create hash, got %x\n", GetLastError());
952 /* Hash the data to compare with the signed hash */
953 result = CryptHashData(hHash2, tests[i].signData, tests[i].dataLen, 0);
954 ok(result, "Failed to add data to hash2, got %x\n", GetLastError());
956 /* Verify signed hash 2 */
957 result = CryptVerifySignatureA(hHash2, signValue2, sizeof(signValue2), pubKey, NULL, 0);
958 ok(result, "Failed to verify signature, got %x\n", GetLastError());
960 result = CryptDestroyHash(hHash1);
961 ok(result, "Failed to destroy hash1, got %x\n", GetLastError());
962 result = CryptDestroyHash(hHash2);
963 ok(result, "Failed to destroy hash2, got %x\n", GetLastError());
965 /* Destroy the public key */
966 result = CryptDestroyKey(pubKey);
967 ok(result, "Failed to destroy public key, got %x\n", GetLastError());
971 static void test_verify_signature(void)
973 HCRYPTPROV hProv = 0;
974 BOOL result;
976 /* acquire base dss provider */
977 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
978 if(!result)
980 skip("DSSENH is currently not available, skipping signature verification tests.\n");
981 return;
983 ok(result, "Failed to acquire CSP.\n");
985 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
987 result = CryptReleaseContext(hProv, 0);
988 ok(result, "Failed to release CSP provider.\n");
990 /* acquire diffie hellman dss provider */
991 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, 0);
992 ok(result, "Failed to acquire CSP.\n");
994 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
996 result = CryptReleaseContext(hProv, 0);
997 ok(result, "Failed to release CSP provider.\n");
999 /* acquire enhanced dss provider */
1000 SetLastError(0xdeadbeef);
1001 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, 0);
1002 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
1004 win_skip("DSSENH and Schannel provider is broken on WinNT4, skipping signature "
1005 "verification tests.\n");
1006 return;
1008 ok(result, "Failed to acquire CSP.\n");
1010 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
1012 result = CryptReleaseContext(hProv, 0);
1013 ok(result, "Failed to release CSP provider.\n");
1015 /* acquire schannel dss provider */
1016 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, 0);
1017 ok(result, "Failed to acquire CSP.\n");
1019 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
1021 result = CryptReleaseContext(hProv, 0);
1022 ok(result, "Failed to release CSP provider.\n");
1025 struct keyExchange_test {
1026 ALG_ID algid;
1027 const BYTE *primeNum;
1028 int primeLen;
1029 const BYTE *generatorNum;
1030 int generatorLen;
1033 /* AT_KEYEXCHANGE interprets to CALG_DH_SF by the DSSENH cryptographic service provider */
1034 static const BYTE primeAT_KEYEXCHANGE[] = {
1035 0x65,0x28,0x24,0xd8,0xbe,0x3f,0x95,0x93, 0x3c,0x4d,0x1b,0x51,0xe1,0x89,0x9a,0x90,
1036 0x5e,0xa0,0x6c,0x25,0xf0,0xb5,0x93,0x98, 0xba,0x76,0x9d,0x54,0x78,0xf6,0xdc,0x04,
1037 0xe1,0xd0,0x87,0x8f,0xa0,0xe4,0x2f,0xb4, 0x09,0x78,0x24,0xbf,0xc8,0x7f,0x59,0xf4,
1038 0x07,0xee,0x07,0x20,0x1b,0x2d,0x54,0x2a, 0xb5,0xb4,0x8f,0x8c,0x33,0x73,0xec,0xaf
1041 static const BYTE generatorAT_KEYEXCHANGE[] = {
1042 0xdc,0x62,0x20,0xe7,0x36,0xa2,0xa6,0xef, 0x77,0x91,0xa8,0xa3,0x6d,0x60,0x70,0x0d,
1043 0x1d,0x79,0xb1,0xbe,0xa8,0x87,0x69,0x39, 0x29,0xaa,0x54,0x27,0x05,0xe6,0x6f,0xa5,
1044 0xde,0x82,0x00,0x5d,0x87,0x1f,0x84,0xf7, 0x40,0xec,0x6f,0x15,0x64,0x02,0x0d,0xb8,
1045 0x50,0x48,0x94,0x66,0xb2,0x7d,0xbd,0xf2, 0x66,0xf8,0x40,0x62,0x94,0xbf,0x24,0x3b
1048 static const BYTE primeCALG_DH_EPHEM[] = {
1049 0x17,0x99,0xa9,0x79,0x31,0xb9,0x05,0xdd, 0x7f,0xf0,0x02,0x11,0x4d,0x0d,0xc3,0x81,
1050 0x8b,0x41,0x50,0x41,0x5f,0x07,0xe6,0x8d, 0x02,0xf9,0xaa,0x86,0x2a,0x07,0x07,0xea,
1051 0x0a,0x75,0xed,0x96,0xa7,0x85,0xee,0xac, 0xb1,0x71,0xbd,0x57,0x48,0xbd,0x41,0x0b,
1052 0xde,0x34,0xe2,0xba,0x5b,0x55,0x64,0x77, 0x84,0xfa,0x96,0xd1,0xaf,0x79,0x49,0x9d
1055 static const BYTE generatorCALG_DH_EPHEM[] = {
1056 0xc7,0x64,0x56,0xde,0xf7,0xb4,0xd3,0xd8, 0xa2,0xd4,0x12,0x2d,0x54,0x5c,0x54,0xc8,
1057 0x04,0x11,0x88,0x14,0x6c,0x9f,0x88,0x41, 0x82,0x93,0x32,0xb1,0x82,0x84,0x5b,0x07,
1058 0x55,0x13,0x82,0x7a,0x64,0x7b,0x12,0x09, 0xe2,0xa0,0x28,0x51,0xf4,0x7a,0xd9,0x26,
1059 0x86,0x95,0x5f,0xc0,0x9a,0x25,0xc2,0x7e, 0x91,0x14,0xdd,0x3c,0x4e,0x86,0x4f,0x6f
1062 static const BYTE primeCALG_DH_SF[] = {
1063 0x85,0xb8,0xa5,0x4a,0xcf,0x2b,0x7c,0x61, 0xb2,0x06,0x93,0x8a,0x87,0x37,0x58,0xb0,
1064 0x8d,0xc7,0x2a,0xa7,0x7f,0x0d,0x74,0xf9, 0x3a,0x7e,0xbc,0xab,0x3a,0x54,0xe4,0x11,
1065 0x69,0x6f,0xcd,0xea,0xad,0x32,0x44,0x4f, 0xee,0x54,0x69,0x8c,0x9c,0x3b,0x87,0x27,
1066 0x36,0x70,0x06,0xf3,0x4e,0xde,0x7f,0x9d, 0xa6,0xf2,0xad,0x43,0x90,0xdd,0xb5,0x9b
1069 static const BYTE generatorCALG_DH_SF[] = {
1070 0xea,0xdc,0xe0,0xbb,0x60,0x26,0xc6,0xb3, 0x93,0x6f,0x61,0xe6,0x7e,0xe2,0xee,0xd6,
1071 0xdb,0x3d,0xca,0xa8,0x31,0x46,0x8f,0x5d, 0xb4,0xaa,0x83,0xd3,0x52,0x10,0xcd,0xfb,
1072 0xfd,0xfc,0x14,0x89,0x0c,0xde,0xcf,0x54, 0x1d,0x05,0x8c,0xbe,0x4a,0xe4,0x37,0xb4,
1073 0xc0,0x15,0x75,0xc5,0xa2,0xfc,0x99,0xfc, 0xad,0x63,0xcb,0x7c,0xb8,0x20,0xdc,0x2b
1076 static const struct keyExchange_test baseDSSkey_data[] = {
1077 /* Cannot exchange keys using the base DSS provider, except on WinNT4 */
1078 {AT_KEYEXCHANGE, primeAT_KEYEXCHANGE, sizeof(primeAT_KEYEXCHANGE), generatorAT_KEYEXCHANGE,
1079 sizeof(generatorAT_KEYEXCHANGE)},
1080 {CALG_DH_EPHEM, primeCALG_DH_EPHEM, sizeof(primeCALG_DH_EPHEM), generatorCALG_DH_EPHEM,
1081 sizeof(generatorCALG_DH_EPHEM)},
1082 {CALG_DH_SF, primeCALG_DH_SF, sizeof(generatorCALG_DH_SF), generatorCALG_DH_SF,
1083 sizeof(generatorCALG_DH_SF)}
1086 static const struct keyExchange_test dssDHkey_data[] = {
1087 {AT_KEYEXCHANGE, primeAT_KEYEXCHANGE, sizeof(primeAT_KEYEXCHANGE), generatorAT_KEYEXCHANGE,
1088 sizeof(generatorAT_KEYEXCHANGE)},
1089 {CALG_DH_EPHEM, primeCALG_DH_EPHEM, sizeof(primeCALG_DH_EPHEM), generatorCALG_DH_EPHEM,
1090 sizeof(generatorCALG_DH_EPHEM)},
1091 {CALG_DH_SF, primeCALG_DH_SF, sizeof(generatorCALG_DH_SF), generatorCALG_DH_SF,
1092 sizeof(generatorCALG_DH_SF)}
1095 static void test_keyExchange_baseDSS(HCRYPTPROV hProv, const struct keyExchange_test *tests, int testLen)
1097 HCRYPTKEY privKey1 = 0, privKey2 = 0;
1098 HCRYPTKEY sessionKey1 = 0, sessionKey2 = 0;
1099 const char plainText[] = "Testing shared key.";
1100 unsigned char pbData1[36];
1101 unsigned char pbData2[36];
1102 BYTE pubKeyBuffer1[512], pubKeyBuffer2[512];
1103 DWORD pubKeyLen1, pubKeyLen2, dataLen;
1104 DATA_BLOB Prime, Generator;
1105 int plainLen = sizeof(plainText), i;
1106 ALG_ID algid;
1107 BOOL result;
1109 for(i = 0; i < testLen; i++)
1111 SetLastError(0xdeadbeef);
1113 /* Create the data blobs and the prime and generator */
1114 Prime.cbData = tests[i].primeLen;
1115 Prime.pbData = (BYTE *)tests[i].primeNum;
1116 Generator.cbData = tests[i].generatorLen;
1117 Generator.pbData = (BYTE *)tests[i].generatorNum;
1119 /* Generate key exchange keys for user1 and user2 */
1120 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey1);
1121 ok((!result && GetLastError() == NTE_BAD_ALGID) || broken(result), /* WinNT4 */
1122 "Expected NTE_BAD_ALGID, got %x\n", GetLastError());
1124 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey2);
1125 ok((!result && GetLastError() == NTE_BAD_ALGID) || broken(result), /* WinNT4 */
1126 "Expected NTE_BAD_ALGID, got %x\n", GetLastError());
1128 /* Set the prime and generator values, which are agreed upon */
1129 result = CryptSetKeyParam(privKey1, KP_P, (BYTE *)&Prime, 0);
1130 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1131 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1133 result = CryptSetKeyParam(privKey2, KP_P, (BYTE *)&Prime, 0);
1134 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1135 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1137 result = CryptSetKeyParam(privKey1, KP_G, (BYTE *)&Generator, 0);
1138 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1139 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1141 result = CryptSetKeyParam(privKey2, KP_G, (BYTE *)&Generator, 0);
1142 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1143 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1145 /* Generate the secret value for user1 and user2 */
1146 result = CryptSetKeyParam(privKey1, KP_X, NULL, 0);
1147 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1148 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1150 result = CryptSetKeyParam(privKey2, KP_X, NULL, 0);
1151 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1152 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1154 /* Acquire required size for the public keys */
1155 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen1);
1156 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1157 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1159 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen2);
1160 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1161 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1163 /* Export public key which will be calculated into the shared key */
1164 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, pubKeyBuffer1, &pubKeyLen1);
1165 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1166 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1168 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, pubKeyBuffer2, &pubKeyLen2);
1169 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1170 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1172 /* Import the public key and convert it into a shared key */
1173 result = CryptImportKey(hProv, pubKeyBuffer2, pubKeyLen2, privKey1, 0, &sessionKey1);
1174 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) ||
1175 broken(!result && GetLastError() == NTE_BAD_DATA) || /* Vista.64 */
1176 broken(!result && GetLastError() == NTE_BAD_TYPE) || /* Win2K-W2K8, Win7.64 */
1177 broken(!result && GetLastError() == NTE_BAD_ALGID), /* W7SP164 (32 bit dssenh) */
1178 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1180 result = CryptImportKey(hProv, pubKeyBuffer1, pubKeyLen1, privKey2, 0, &sessionKey2);
1181 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) ||
1182 broken(!result && GetLastError() == NTE_BAD_DATA) || /* Win 7 */
1183 broken(!result && GetLastError() == NTE_BAD_TYPE) || /* Win2K-W2K8, Win7.64 */
1184 broken(!result && GetLastError() == NTE_BAD_ALGID), /* W7SP164 (32 bit dssenh) */
1185 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1187 /* Set the shared key parameters to matching type */
1188 algid = CALG_RC4;
1189 result = CryptSetKeyParam(sessionKey1, KP_ALGID, (BYTE *)&algid, 0);
1190 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1191 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1193 algid = CALG_RC4;
1194 result = CryptSetKeyParam(sessionKey2, KP_ALGID, (BYTE *)&algid, 0);
1195 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1196 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1198 /* Encrypt some data and verify we are getting the same output */
1199 memcpy(pbData1, plainText, plainLen);
1200 dataLen = plainLen;
1202 result = CryptEncrypt(sessionKey1, 0, TRUE, 0, pbData1, &dataLen, 36);
1203 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1204 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1206 result = CryptDecrypt(sessionKey2, 0, TRUE, 0, pbData1, &dataLen);
1207 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1208 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1210 ok(!memcmp(pbData1, (BYTE *)plainText, sizeof(plainText)), "Incorrect decrypted data.\n");
1212 memcpy(pbData2, plainText, plainLen);
1213 dataLen = plainLen;
1215 result = CryptEncrypt(sessionKey2, 0, TRUE, 0, pbData2, &dataLen, 36);
1216 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1217 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1219 result = CryptDecrypt(sessionKey1, 0, TRUE, 0, pbData2, &dataLen);
1220 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1221 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1223 ok(!memcmp(pbData1, pbData2, dataLen), "Decrypted data is not identical.\n");
1225 /* Destroy all user keys */
1226 result = CryptDestroyKey(sessionKey1);
1227 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1228 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1230 result = CryptDestroyKey(sessionKey2);
1231 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1232 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1234 result = CryptDestroyKey(privKey1);
1235 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1236 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1238 result = CryptDestroyKey(privKey2);
1239 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1240 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1244 static void test_keyExchange_dssDH(HCRYPTPROV hProv, const struct keyExchange_test *tests, int testLen)
1246 HCRYPTKEY privKey1 = 0, privKey2 = 0;
1247 HCRYPTKEY sessionKey1 = 0, sessionKey2 = 0;
1248 const char plainText[] = "Testing shared key.";
1249 unsigned char pbData1[36];
1250 unsigned char pbData2[36];
1251 BYTE pubKeyBuffer1[512], pubKeyBuffer2[512];
1252 DWORD pubKeyLen1, pubKeyLen2, dataLen;
1253 DATA_BLOB Prime, Generator;
1254 int plainLen = sizeof(plainText), i;
1255 ALG_ID algid;
1256 BOOL result;
1258 for(i = 0; i < testLen; i++)
1260 SetLastError(0xdeadbeef);
1262 /* Create the data blobs and the prime and generator */
1263 Prime.cbData = tests[i].primeLen;
1264 Prime.pbData = (BYTE *)tests[i].primeNum;
1265 Generator.cbData = tests[i].generatorLen;
1266 Generator.pbData = (BYTE *)tests[i].generatorNum;
1268 /* Generate key exchange keys for user1 and user2 */
1269 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey1);
1270 ok(result, "Failed to generate a key for user1, got %x\n", GetLastError());
1272 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey2);
1273 ok(result, "Failed to generate a key for user2, got %x\n", GetLastError());
1275 /* Set the prime and generator values, which are agreed upon */
1276 result = CryptSetKeyParam(privKey1, KP_P, (BYTE *)&Prime, 0);
1277 ok(result, "Failed to set prime for user 1's key, got %x\n", GetLastError());
1279 result = CryptSetKeyParam(privKey2, KP_P, (BYTE *)&Prime, 0);
1280 ok(result, "Failed to set prime for user 2's key, got %x\n", GetLastError());
1282 result = CryptSetKeyParam(privKey1, KP_G, (BYTE *)&Generator, 0);
1283 ok(result, "Failed to set generator for user 1's key, got %x\n", GetLastError());
1285 result = CryptSetKeyParam(privKey2, KP_G, (BYTE *)&Generator, 0);
1286 ok(result, "Failed to set generator for user 2's key, got %x\n", GetLastError());
1288 /* Generate the secret value for user1 and user2 */
1289 result = CryptSetKeyParam(privKey1, KP_X, NULL, 0);
1290 ok(result || broken(!result && GetLastError() == ERROR_INVALID_PARAMETER),
1291 "Failed to set secret value for user 1, got %x\n", GetLastError());/* Win2k & WinXP */
1293 result = CryptSetKeyParam(privKey2, KP_X, NULL, 0);
1294 ok(result || broken(!result && GetLastError() == ERROR_INVALID_PARAMETER),
1295 "Failed to set secret value for user 2, got %x\n", GetLastError());/* Win2k & WinXP */
1297 /* Acquire required size for the public keys */
1298 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen1);
1299 ok(result, "Failed to acquire public key length for user 1, got %x\n", GetLastError());
1301 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen2);
1302 ok(result, "Failed to acquire public key length for user 2, got %x\n", GetLastError());
1304 /* Export public key which will be calculated into the shared key */
1305 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, pubKeyBuffer1, &pubKeyLen1);
1306 ok(result, "Failed to export public key for user 1, got %x\n", GetLastError());
1308 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, pubKeyBuffer2, &pubKeyLen2);
1309 ok(result, "Failed to export public key for user 2, got %x\n", GetLastError());
1311 /* Import the public key and convert it into a shared key */
1312 result = CryptImportKey(hProv, pubKeyBuffer2, pubKeyLen2, privKey1, 0, &sessionKey1);
1313 ok(result, "Failed to import key for user 1, got %x\n", GetLastError());
1315 result = CryptImportKey(hProv, pubKeyBuffer1, pubKeyLen1, privKey2, 0, &sessionKey2);
1316 ok(result, "Failed to import key for user 2, got %x\n", GetLastError());
1318 /* Set the shared key parameters to matching cipher type */
1319 algid = CALG_3DES;
1320 result = CryptSetKeyParam(sessionKey1, KP_ALGID, (BYTE *)&algid, 0);
1321 ok(result, "Failed to set session key for user 1, got %x\n", GetLastError());
1323 algid = CALG_3DES;
1324 result = CryptSetKeyParam(sessionKey2, KP_ALGID, (BYTE *)&algid, 0);
1325 ok(result, "Failed to set session key for user 2, got %x\n", GetLastError());
1327 /* Encrypt some data and verify we are getting the correct output */
1328 memcpy(pbData1, plainText, plainLen);
1329 dataLen = plainLen;
1331 result = CryptEncrypt(sessionKey1, 0, TRUE, 0, pbData1, &dataLen, 36);
1332 ok(result, "Failed to encrypt data, got %x.\n", GetLastError());
1334 result = CryptDecrypt(sessionKey2, 0, TRUE, 0, pbData1, &dataLen);
1335 ok(result, "Failed to decrypt data, got %x.\n", GetLastError());
1337 ok(!memcmp(pbData1, (BYTE *)plainText, sizeof(plainText)), "Incorrect decrypted data.\n");
1339 memcpy(pbData2, plainText, plainLen);
1340 dataLen = plainLen;
1342 result = CryptEncrypt(sessionKey2, 0, TRUE, 0, pbData2, &dataLen, 36);
1343 ok(result, "Failed to encrypt data, got %x.\n", GetLastError());
1345 result = CryptDecrypt(sessionKey1, 0, TRUE, 0, pbData2, &dataLen);
1346 ok(result, "Failed to decrypt data, got %x.\n", GetLastError());
1348 ok(!memcmp(pbData1, pbData2, dataLen), "Decrypted data is not identical.\n");
1350 /* Destroy all user keys */
1351 result = CryptDestroyKey(sessionKey1);
1352 ok(result, "Failed to destroy session key 1, got %x\n", GetLastError());
1354 result = CryptDestroyKey(sessionKey2);
1355 ok(result, "Failed to destroy session key 2, got %x\n", GetLastError());
1357 result = CryptDestroyKey(privKey1);
1358 ok(result, "Failed to destroy key private key 1, got %x\n", GetLastError());
1360 result = CryptDestroyKey(privKey2);
1361 ok(result, "Failed to destroy key private key 2, got %x\n", GetLastError());
1365 static void test_key_exchange(void)
1367 HCRYPTPROV hProv = 0;
1368 BOOL result;
1370 /* acquire base dss provider */
1371 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
1372 if(!result)
1374 skip("DSSENH is currently not available, skipping shared key tests.\n");
1375 return;
1377 ok(result, "Failed to acquire CSP.\n");
1379 test_keyExchange_baseDSS(hProv, baseDSSkey_data, TESTLEN(baseDSSkey_data));
1381 result = CryptReleaseContext(hProv, 0);
1382 ok(result, "Failed to release CSP provider.\n");
1384 /* acquire diffie hellman dss provider */
1385 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH,
1386 CRYPT_VERIFYCONTEXT);
1387 ok(result, "Failed to acquire CSP.\n");
1389 test_keyExchange_dssDH(hProv, dssDHkey_data, TESTLEN(dssDHkey_data));
1391 result = CryptReleaseContext(hProv, 0);
1392 ok(result, "Failed to release CSP provider.\n");
1394 /* acquire enhanced dss provider */
1395 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH,
1396 CRYPT_VERIFYCONTEXT);
1397 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
1399 win_skip("DSSENH and Schannel provider is broken on WinNT4, skipping shared key tests.\n");
1400 return;
1402 ok(result, "Failed to acquire CSP.\n");
1404 test_keyExchange_dssDH(hProv, dssDHkey_data, TESTLEN(dssDHkey_data));
1406 result = CryptReleaseContext(hProv, 0);
1407 ok(result, "Failed to release CSP provider.\n");
1409 /* acquire schannel dss provider */
1410 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL,
1411 CRYPT_VERIFYCONTEXT);
1412 ok(result, "Failed to acquire CSP.\n");
1414 test_keyExchange_dssDH(hProv, dssDHkey_data, TESTLEN(dssDHkey_data));
1416 result = CryptReleaseContext(hProv, 0);
1417 ok(result, "Failed to release CSP provider.\n");
1420 START_TEST(dssenh)
1422 test_acquire_context();
1423 test_keylength();
1424 test_hash(hash_data, TESTLEN(hash_data));
1425 test_data_encryption(encrypt_data, TESTLEN(encrypt_data));
1426 test_cipher_modes(ciphermode_data, TESTLEN(ciphermode_data));
1427 test_verify_signature();
1428 test_key_exchange();