[CRYPT32_WINETEST] Add a PCH.
[reactos.git] / modules / rostests / winetests / crypt32 / msg.c
1 /*
2 * Unit test suite for crypt32.dll's CryptMsg functions
3 *
4 * Copyright 2007 Juan Lang
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include "precomp.h"
22
23 static BOOL have_nt = TRUE;
24 static BOOL old_crypt32 = FALSE;
25 static char oid_rsa_md5[] = szOID_RSA_MD5;
26
27 static BOOL (WINAPI * pCryptAcquireContextA)
28 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
29 static BOOL (WINAPI * pCryptAcquireContextW)
30 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
31
32 static void init_function_pointers(void)
33 {
34 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
35
36 #define GET_PROC(dll, func) \
37 p ## func = (void *)GetProcAddress(dll, #func); \
38 if(!p ## func) \
39 trace("GetProcAddress(%s) failed\n", #func);
40
41 GET_PROC(hAdvapi32, CryptAcquireContextA)
42 GET_PROC(hAdvapi32, CryptAcquireContextW)
43
44 #undef GET_PROC
45 }
46
47 static void test_msg_open_to_encode(void)
48 {
49 HCRYPTMSG msg;
50
51 /* Crash
52 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
53 NULL, NULL);
54 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
55 NULL);
56 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
57 NULL);
58 */
59
60 /* Bad encodings */
61 SetLastError(0xdeadbeef);
62 msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
63 ok(!msg && GetLastError() == E_INVALIDARG,
64 "Expected E_INVALIDARG, got %x\n", GetLastError());
65 SetLastError(0xdeadbeef);
66 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
67 ok(!msg && GetLastError() == E_INVALIDARG,
68 "Expected E_INVALIDARG, got %x\n", GetLastError());
69
70 /* Bad message types */
71 SetLastError(0xdeadbeef);
72 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
73 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
74 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
75 SetLastError(0xdeadbeef);
76 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
77 NULL, NULL, NULL);
78 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
79 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
80 SetLastError(0xdeadbeef);
81 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
82 CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
83 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
84 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
85 SetLastError(0xdeadbeef);
86 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
87 NULL, NULL);
88 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
89 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
90 }
91
92 static void test_msg_open_to_decode(void)
93 {
94 HCRYPTMSG msg;
95 CMSG_STREAM_INFO streamInfo = { 0 };
96
97 SetLastError(0xdeadbeef);
98 msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
99 ok(!msg && GetLastError() == E_INVALIDARG,
100 "Expected E_INVALIDARG, got %x\n", GetLastError());
101
102 /* Bad encodings */
103 SetLastError(0xdeadbeef);
104 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
105 ok(!msg && GetLastError() == E_INVALIDARG,
106 "Expected E_INVALIDARG, got %x\n", GetLastError());
107 SetLastError(0xdeadbeef);
108 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
109 ok(!msg && GetLastError() == E_INVALIDARG,
110 "Expected E_INVALIDARG, got %x\n", GetLastError());
111
112 /* The message type can be explicit... */
113 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
114 NULL);
115 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
116 CryptMsgClose(msg);
117 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
118 NULL);
119 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
120 CryptMsgClose(msg);
121 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
122 NULL);
123 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
124 CryptMsgClose(msg);
125 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
126 NULL);
127 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
128 CryptMsgClose(msg);
129 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
130 CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
131 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
132 CryptMsgClose(msg);
133 /* or implicit.. */
134 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
135 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
136 CryptMsgClose(msg);
137 /* or even invalid. */
138 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
139 NULL);
140 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
141 CryptMsgClose(msg);
142 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
143 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
144 CryptMsgClose(msg);
145
146 /* And even though the stream info parameter "must be set to NULL" for
147 * CMSG_HASHED, it's still accepted.
148 */
149 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
150 &streamInfo);
151 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
152 CryptMsgClose(msg);
153 }
154
155 static void test_msg_get_param(void)
156 {
157 BOOL ret;
158 HCRYPTMSG msg;
159 DWORD size, i, value;
160
161 /* Crash
162 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
163 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
164 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
165 */
166
167 /* Decoded messages */
168 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
169 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
170 /* For decoded messages, the type is always available */
171 size = 0;
172 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
173 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
174 size = sizeof(value);
175 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
176 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
177 /* For this (empty) message, the type isn't set */
178 ok(value == 0, "Expected type 0, got %d\n", value);
179 CryptMsgClose(msg);
180
181 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
182 NULL);
183 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
184 /* For explicitly typed messages, the type is known. */
185 size = sizeof(value);
186 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
187 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
188 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
189 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
190 {
191 size = 0;
192 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
193 ok(!ret, "Parameter %d: expected failure\n", i);
194 }
195 CryptMsgClose(msg);
196
197 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
198 NULL);
199 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
200 size = sizeof(value);
201 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
202 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
203 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
204 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
205 {
206 size = 0;
207 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
208 ok(!ret, "Parameter %d: expected failure\n", i);
209 }
210 CryptMsgClose(msg);
211
212 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
213 NULL);
214 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
215 size = sizeof(value);
216 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
217 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
218 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
219 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
220 {
221 size = 0;
222 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
223 ok(!ret, "Parameter %d: expected failure\n", i);
224 }
225 CryptMsgClose(msg);
226
227 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
228 NULL);
229 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
230 size = sizeof(value);
231 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
232 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
233 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
234 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
235 {
236 size = 0;
237 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
238 ok(!ret, "Parameter %d: expected failure\n", i);
239 }
240 CryptMsgClose(msg);
241
242 /* Explicitly typed messages get their types set, even if they're invalid */
243 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
244 NULL);
245 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
246 size = sizeof(value);
247 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
248 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
249 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
250 CryptMsgClose(msg);
251
252 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
253 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
254 size = sizeof(value);
255 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
256 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
257 ok(value == 1000, "Expected 1000, got %d\n", value);
258 CryptMsgClose(msg);
259 }
260
261 static void test_msg_close(void)
262 {
263 BOOL ret;
264 HCRYPTMSG msg;
265
266 /* NULL succeeds.. */
267 ret = CryptMsgClose(NULL);
268 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
269 /* but an arbitrary pointer crashes. */
270 if (0)
271 ret = CryptMsgClose((HCRYPTMSG)1);
272 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
273 NULL);
274 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
275 ret = CryptMsgClose(msg);
276 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
277 }
278
279 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
280 const BYTE *expected, DWORD expectedSize)
281 {
282 DWORD size;
283 LPBYTE buf;
284 BOOL ret;
285
286 size = 0xdeadbeef;
287 ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
288 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */ ||
289 GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x, for some params */),
290 "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
291 if (!ret)
292 {
293 win_skip("parameter %d not supported, skipping tests\n", param);
294 return;
295 }
296 buf = HeapAlloc(GetProcessHeap(), 0, size);
297 ret = CryptMsgGetParam(msg, param, 0, buf, &size);
298 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
299 ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
300 expectedSize, size);
301 if (size == expectedSize && size)
302 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
303 HeapFree(GetProcessHeap(), 0, buf);
304 }
305
306 static void test_data_msg_open(void)
307 {
308 HCRYPTMSG msg;
309 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
310 CMSG_STREAM_INFO streamInfo = { 0 };
311 char oid[] = "1.2.3";
312
313 /* The data message type takes no additional info */
314 SetLastError(0xdeadbeef);
315 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
316 NULL, NULL);
317 ok(!msg && GetLastError() == E_INVALIDARG,
318 "Expected E_INVALIDARG, got %x\n", GetLastError());
319 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
320 NULL);
321 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
322 CryptMsgClose(msg);
323
324 /* An empty stream info is allowed. */
325 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
326 &streamInfo);
327 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
328 CryptMsgClose(msg);
329
330 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
331 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
332 NULL);
333 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
334 CryptMsgClose(msg);
335 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
336 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
337 CMSG_DATA, NULL, oid, NULL);
338 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
339 CryptMsgClose(msg);
340 /* and when a stream info is given, even though you're not supposed to be
341 * able to use anything but szOID_RSA_data when streaming is being used.
342 */
343 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
344 CMSG_DATA, NULL, oid, &streamInfo);
345 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
346 CryptMsgClose(msg);
347 }
348
349 static const BYTE msgData[] = { 1, 2, 3, 4 };
350
351 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
352 BOOL final)
353 {
354 return TRUE;
355 }
356
357 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
358
359 static void test_data_msg_update(void)
360 {
361 HCRYPTMSG msg;
362 BOOL ret;
363 CMSG_STREAM_INFO streamInfo = { 0 };
364
365 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
366 NULL);
367 /* Can't update a message that wasn't opened detached with final = FALSE */
368 SetLastError(0xdeadbeef);
369 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
370 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
371 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
372 /* Updating it with final = TRUE succeeds */
373 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
374 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
375 /* Any subsequent update will fail, as the last was final */
376 SetLastError(0xdeadbeef);
377 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
378 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
379 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
380 CryptMsgClose(msg);
381
382 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
383 NULL);
384 /* Starting with Vista, can update a message with no data. */
385 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
386 ok(ret || broken(!ret), "CryptMsgUpdate failed: %08x\n", GetLastError());
387 if (ret)
388 {
389 DWORD size;
390
391 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
392 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
393 if (ret)
394 {
395 LPBYTE buf = CryptMemAlloc(size);
396
397 if (buf)
398 {
399 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, buf,
400 &size);
401 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
402 if (ret)
403 {
404 ok(size == sizeof(dataEmptyBareContent),
405 "unexpected size %d\n", size);
406 ok(!memcmp(buf, dataEmptyBareContent, size),
407 "unexpected value\n");
408 }
409 CryptMemFree(buf);
410 }
411 }
412 }
413 CryptMsgClose(msg);
414
415 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
416 CMSG_DATA, NULL, NULL, NULL);
417 if (have_nt)
418 {
419 /* Doesn't appear to be able to update CMSG-DATA with non-final updates.
420 * On Win9x, this sometimes succeeds, sometimes fails with
421 * GetLastError() == 0, so it's not worth checking there.
422 */
423 SetLastError(0xdeadbeef);
424 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
425 ok(!ret &&
426 (GetLastError() == E_INVALIDARG ||
427 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
428 "Expected E_INVALIDARG, got %x\n", GetLastError());
429 SetLastError(0xdeadbeef);
430 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
431 ok(!ret &&
432 (GetLastError() == E_INVALIDARG ||
433 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
434 "Expected E_INVALIDARG, got %x\n", GetLastError());
435 }
436 else
437 skip("not updating CMSG_DATA with a non-final update\n");
438 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
439 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
440 CryptMsgClose(msg);
441
442 if (!old_crypt32)
443 {
444 /* Calling update after opening with an empty stream info (with a bogus
445 * output function) yields an error:
446 */
447 /* Crashes on some Win9x */
448 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
449 &streamInfo);
450 SetLastError(0xdeadbeef);
451 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
452 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
453 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
454 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
455 GetLastError());
456 CryptMsgClose(msg);
457 }
458 /* Calling update with a valid output function succeeds, even if the data
459 * exceeds the size specified in the stream info.
460 */
461 streamInfo.pfnStreamOutput = nop_stream_output;
462 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
463 &streamInfo);
464 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
465 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
466 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
467 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
468 CryptMsgClose(msg);
469 }
470
471 static void test_data_msg_get_param(void)
472 {
473 HCRYPTMSG msg;
474 DWORD size;
475 BOOL ret;
476 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
477
478 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
479 NULL);
480
481 /* Content and bare content are always gettable when not streaming */
482 size = 0;
483 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
484 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
485 size = 0;
486 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
487 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
488 /* But for this type of message, the signer and hash aren't applicable,
489 * and the type isn't available.
490 */
491 size = 0;
492 SetLastError(0xdeadbeef);
493 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
494 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
495 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
496 SetLastError(0xdeadbeef);
497 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
498 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
499 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
500 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
501 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
502 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
503 CryptMsgClose(msg);
504
505 /* Can't get content or bare content when streaming */
506 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
507 NULL, &streamInfo);
508 SetLastError(0xdeadbeef);
509 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
510 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
511 "Expected E_INVALIDARG, got %x\n", GetLastError());
512 SetLastError(0xdeadbeef);
513 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
514 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
515 "Expected E_INVALIDARG, got %x\n", GetLastError());
516 CryptMsgClose(msg);
517 }
518
519 static const BYTE dataEmptyContent[] = {
520 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
521 0x04,0x00 };
522 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
523 static const BYTE dataContent[] = {
524 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
525 0x04,0x04,0x01,0x02,0x03,0x04 };
526
527 struct update_accum
528 {
529 DWORD cUpdates;
530 CRYPT_DATA_BLOB *updates;
531 };
532
533 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
534 DWORD cb, BOOL final)
535 {
536 struct update_accum *accum = (struct update_accum *)pvArg;
537 BOOL ret = FALSE;
538
539 if (accum->cUpdates)
540 accum->updates = CryptMemRealloc(accum->updates,
541 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
542 else
543 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
544 if (accum->updates)
545 {
546 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
547
548 blob->pbData = CryptMemAlloc(cb);
549 if (blob->pbData)
550 {
551 memcpy(blob->pbData, pb, cb);
552 blob->cbData = cb;
553 ret = TRUE;
554 }
555 accum->cUpdates++;
556 }
557 return ret;
558 }
559
560 /* The updates of a (bogus) definite-length encoded message */
561 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
562 0x07,0x01,0xa0,0x02,0x04,0x00 };
563 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
564 static CRYPT_DATA_BLOB b1[] = {
565 { sizeof(u1), u1 },
566 { sizeof(u2), u2 },
567 { sizeof(u2), u2 },
568 };
569 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
570 /* The updates of a definite-length encoded message */
571 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
572 0x07,0x01,0xa0,0x06,0x04,0x04 };
573 static CRYPT_DATA_BLOB b2[] = {
574 { sizeof(u3), u3 },
575 { sizeof(u2), u2 },
576 };
577 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
578 /* The updates of an indefinite-length encoded message */
579 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
580 0x07,0x01,0xa0,0x80,0x24,0x80 };
581 static BYTE u5[] = { 0x04,0x04 };
582 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
583 static CRYPT_DATA_BLOB b3[] = {
584 { sizeof(u4), u4 },
585 { sizeof(u5), u5 },
586 { sizeof(u2), u2 },
587 { sizeof(u5), u5 },
588 { sizeof(u2), u2 },
589 { sizeof(u6), u6 },
590 };
591 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
592
593 static void check_updates(LPCSTR header, const struct update_accum *expected,
594 const struct update_accum *got)
595 {
596 DWORD i;
597
598 ok(expected->cUpdates == got->cUpdates,
599 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
600 got->cUpdates);
601 if (expected->cUpdates == got->cUpdates)
602 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
603 {
604 ok(expected->updates[i].cbData == got->updates[i].cbData,
605 "%s, update %d: expected %d bytes, got %d\n", header, i,
606 expected->updates[i].cbData, got->updates[i].cbData);
607 if (expected->updates[i].cbData && expected->updates[i].cbData ==
608 got->updates[i].cbData)
609 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
610 got->updates[i].cbData), "%s, update %d: unexpected value\n",
611 header, i);
612 }
613 }
614
615 /* Frees the updates stored in accum */
616 static void free_updates(struct update_accum *accum)
617 {
618 DWORD i;
619
620 for (i = 0; i < accum->cUpdates; i++)
621 CryptMemFree(accum->updates[i].pbData);
622 CryptMemFree(accum->updates);
623 accum->updates = NULL;
624 accum->cUpdates = 0;
625 }
626
627 static void test_data_msg_encoding(void)
628 {
629 HCRYPTMSG msg;
630 BOOL ret;
631 static char oid[] = "1.2.3";
632 struct update_accum accum = { 0, NULL };
633 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
634
635 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
636 NULL);
637 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
638 dataEmptyBareContent, sizeof(dataEmptyBareContent));
639 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
640 sizeof(dataEmptyContent));
641 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
642 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
643 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
644 dataBareContent, sizeof(dataBareContent));
645 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
646 sizeof(dataContent));
647 CryptMsgClose(msg);
648 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
649 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
650 CMSG_DATA, NULL, NULL, NULL);
651 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
652 dataEmptyBareContent, sizeof(dataEmptyBareContent));
653 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
654 sizeof(dataEmptyContent));
655 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
656 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
657 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
658 dataBareContent, sizeof(dataBareContent));
659 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
660 sizeof(dataContent));
661 CryptMsgClose(msg);
662 /* The inner OID is apparently ignored */
663 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
664 NULL);
665 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
666 dataEmptyBareContent, sizeof(dataEmptyBareContent));
667 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
668 dataEmptyContent, sizeof(dataEmptyContent));
669 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
670 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
671 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
672 dataBareContent, sizeof(dataBareContent));
673 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
674 sizeof(dataContent));
675 CryptMsgClose(msg);
676 /* A streaming message is DER encoded if the length is not 0xffffffff, but
677 * curiously, updates aren't validated to make sure they don't exceed the
678 * stated length. (The resulting output will of course fail to decode.)
679 */
680 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
681 NULL, &streamInfo);
682 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
683 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
684 CryptMsgClose(msg);
685 check_updates("bogus data message with definite length", &a1, &accum);
686 free_updates(&accum);
687 /* A valid definite-length encoding: */
688 streamInfo.cbContent = sizeof(msgData);
689 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
690 NULL, &streamInfo);
691 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
692 CryptMsgClose(msg);
693 check_updates("data message with definite length", &a2, &accum);
694 free_updates(&accum);
695 /* An indefinite-length encoding: */
696 streamInfo.cbContent = 0xffffffff;
697 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
698 NULL, &streamInfo);
699 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
700 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
701 CryptMsgClose(msg);
702 check_updates("data message with indefinite length", &a3, &accum);
703 free_updates(&accum);
704 }
705
706 static void test_data_msg(void)
707 {
708 test_data_msg_open();
709 test_data_msg_update();
710 test_data_msg_get_param();
711 test_data_msg_encoding();
712 }
713
714 static void test_hash_msg_open(void)
715 {
716 HCRYPTMSG msg;
717 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
718 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
719
720 SetLastError(0xdeadbeef);
721 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
722 NULL, NULL);
723 ok(!msg && GetLastError() == E_INVALIDARG,
724 "Expected E_INVALIDARG, got %x\n", GetLastError());
725 hashInfo.cbSize = sizeof(hashInfo);
726 SetLastError(0xdeadbeef);
727 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
728 NULL, NULL);
729 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
730 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
731 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
732 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
733 NULL, NULL);
734 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
735 CryptMsgClose(msg);
736 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
737 CMSG_HASHED, &hashInfo, NULL, NULL);
738 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
739 CryptMsgClose(msg);
740 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
741 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
742 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
743 CryptMsgClose(msg);
744 }
745
746 static void test_hash_msg_update(void)
747 {
748 HCRYPTMSG msg;
749 BOOL ret;
750 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
751 { oid_rsa_md5, { 0, NULL } }, NULL };
752 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
753
754 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
755 CMSG_HASHED, &hashInfo, NULL, NULL);
756 /* Detached hashed messages opened in non-streaming mode allow non-final
757 * updates..
758 */
759 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
760 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
761 /* including non-final updates with no data.. */
762 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
763 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
764 /* and final updates with no data. */
765 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
766 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
767 /* But no updates are allowed after the final update. */
768 SetLastError(0xdeadbeef);
769 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
770 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
771 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
772 SetLastError(0xdeadbeef);
773 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
774 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
775 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
776 CryptMsgClose(msg);
777 /* Non-detached messages, in contrast, don't allow non-final updates in
778 * non-streaming mode.
779 */
780 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
781 NULL, NULL);
782 SetLastError(0xdeadbeef);
783 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
784 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
785 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
786 /* Final updates (including empty ones) are allowed. */
787 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
788 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
789 CryptMsgClose(msg);
790 /* And, of course, streaming mode allows non-final updates */
791 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
792 NULL, &streamInfo);
793 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
794 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
795 CryptMsgClose(msg);
796 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
797 * to be a bug, it isn't actually used - see encoding tests.)
798 */
799 streamInfo.pfnStreamOutput = NULL;
800 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
801 NULL, &streamInfo);
802 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
803 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
804 CryptMsgClose(msg);
805 }
806
807 static const BYTE emptyHashParam[] = {
808 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
809 0x7e };
810
811 static void test_hash_msg_get_param(void)
812 {
813 HCRYPTMSG msg;
814 BOOL ret;
815 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
816 { oid_rsa_md5, { 0, NULL } }, NULL };
817 DWORD size, value;
818 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
819 BYTE buf[16];
820
821 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
822 NULL, NULL);
823 /* Content and bare content are always gettable for non-streamed messages */
824 size = 0;
825 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
826 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
827 "CryptMsgGetParam failed: %08x\n", GetLastError());
828 size = 0;
829 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
830 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
831 "CryptMsgGetParam failed: %08x\n", GetLastError());
832 /* For an encoded hash message, the hash data aren't available */
833 SetLastError(0xdeadbeef);
834 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
835 ok(!ret && (GetLastError() == CRYPT_E_INVALID_MSG_TYPE ||
836 GetLastError() == OSS_LIMITED /* Win9x */),
837 "Expected CRYPT_E_INVALID_MSG_TYPE or OSS_LIMITED, got %08x\n",
838 GetLastError());
839 /* The hash is also available. */
840 size = 0;
841 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
842 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
843 ok(size == sizeof(buf), "Unexpected size %d\n", size);
844 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
845 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
846 ok(size == sizeof(buf), "Unexpected size %d\n", size);
847 if (size == sizeof(buf))
848 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
849 /* By getting the hash, further updates are not allowed */
850 SetLastError(0xdeadbeef);
851 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
852 ok(!ret &&
853 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
854 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
855 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
856 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
857 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
858
859 /* Even after a final update, the hash data aren't available */
860 SetLastError(0xdeadbeef);
861 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
862 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
863 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
864 /* The version is also available, and should be zero for this message. */
865 size = 0;
866 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
867 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
868 "CryptMsgGetParam failed: %08x\n", GetLastError());
869 size = sizeof(value);
870 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
871 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
872 "CryptMsgGetParam failed: %08x\n", GetLastError());
873 if (ret)
874 ok(value == 0, "Expected version 0, got %d\n", value);
875 /* As usual, the type isn't available. */
876 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
877 ok(!ret, "Expected failure\n");
878 CryptMsgClose(msg);
879
880 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
881 NULL, &streamInfo);
882 /* Streamed messages don't allow you to get the content or bare content. */
883 SetLastError(0xdeadbeef);
884 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
885 ok(!ret && (GetLastError() == E_INVALIDARG ||
886 GetLastError() == OSS_LIMITED /* Win9x */),
887 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
888 SetLastError(0xdeadbeef);
889 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
890 ok(!ret && (GetLastError() == E_INVALIDARG ||
891 GetLastError() == OSS_LIMITED /* Win9x */),
892 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
893 /* The hash is still available. */
894 size = 0;
895 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
896 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
897 ok(size == sizeof(buf), "Unexpected size %d\n", size);
898 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
899 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
900 if (size == sizeof(buf))
901 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
902 /* After updating the hash, further updates aren't allowed on streamed
903 * messages either.
904 */
905 SetLastError(0xdeadbeef);
906 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
907 ok(!ret &&
908 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
909 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
910 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
911 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
912 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
913
914 CryptMsgClose(msg);
915 }
916
917 static const BYTE hashEmptyBareContent[] = {
918 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
919 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
920 static const BYTE hashEmptyContent[] = {
921 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
922 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
923 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
924 static const BYTE hashBareContent[] = {
925 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
926 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
927 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
928 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
929 static const BYTE hashContent[] = {
930 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
931 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
932 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
933 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
934 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
935
936 static const BYTE detachedHashNonFinalBareContent[] = {
937 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
938 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
939 0x07,0x01,0x04,0x00 };
940 static const BYTE detachedHashNonFinalContent[] = {
941 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
942 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
943 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
944 0x07,0x01,0x04,0x00 };
945 static const BYTE detachedHashBareContent[] = {
946 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
947 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
948 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
949 0x9d,0x2a,0x8f,0x26,0x2f };
950 static const BYTE detachedHashContent[] = {
951 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
952 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
953 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
954 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
955 0x9d,0x2a,0x8f,0x26,0x2f };
956
957 static void test_hash_msg_encoding(void)
958 {
959 HCRYPTMSG msg;
960 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
961 BOOL ret;
962 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
963 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
964
965 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
966 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
967 NULL, NULL);
968 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
969 hashEmptyBareContent, sizeof(hashEmptyBareContent));
970 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
971 hashEmptyContent, sizeof(hashEmptyContent));
972 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
973 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
974 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
975 hashBareContent, sizeof(hashBareContent));
976 check_param("hash content", msg, CMSG_CONTENT_PARAM,
977 hashContent, sizeof(hashContent));
978 CryptMsgClose(msg);
979 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
980 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
981 CMSG_HASHED, &hashInfo, NULL, NULL);
982 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
983 hashEmptyBareContent, sizeof(hashEmptyBareContent));
984 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
985 hashEmptyContent, sizeof(hashEmptyContent));
986 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
987 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
988 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
989 hashBareContent, sizeof(hashBareContent));
990 check_param("hash content", msg, CMSG_CONTENT_PARAM,
991 hashContent, sizeof(hashContent));
992 CryptMsgClose(msg);
993 /* Same test, but with CMSG_DETACHED_FLAG set */
994 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
995 CMSG_HASHED, &hashInfo, NULL, NULL);
996 check_param("detached hash empty bare content", msg,
997 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
998 sizeof(hashEmptyBareContent));
999 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
1000 hashEmptyContent, sizeof(hashEmptyContent));
1001 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1002 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1003 check_param("detached hash not final bare content", msg,
1004 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
1005 sizeof(detachedHashNonFinalBareContent));
1006 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
1007 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
1008 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1009 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1010 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1011 detachedHashBareContent, sizeof(detachedHashBareContent));
1012 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1013 detachedHashContent, sizeof(detachedHashContent));
1014 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1015 detachedHashBareContent, sizeof(detachedHashBareContent));
1016 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1017 detachedHashContent, sizeof(detachedHashContent));
1018 CryptMsgClose(msg);
1019 /* In what appears to be a bug, streamed updates to hash messages don't
1020 * call the output function.
1021 */
1022 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
1023 NULL, &streamInfo);
1024 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1025 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1026 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1027 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1028 CryptMsgClose(msg);
1029 check_updates("empty hash message", &empty_accum, &accum);
1030 free_updates(&accum);
1031
1032 streamInfo.cbContent = sizeof(msgData);
1033 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
1034 NULL, &streamInfo);
1035 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1036 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1037 CryptMsgClose(msg);
1038 check_updates("hash message", &empty_accum, &accum);
1039 free_updates(&accum);
1040
1041 streamInfo.cbContent = sizeof(msgData);
1042 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
1043 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
1044 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1045 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1046 CryptMsgClose(msg);
1047 check_updates("detached hash message", &empty_accum, &accum);
1048 free_updates(&accum);
1049 }
1050
1051 static void test_hash_msg(void)
1052 {
1053 test_hash_msg_open();
1054 test_hash_msg_update();
1055 test_hash_msg_get_param();
1056 test_hash_msg_encoding();
1057 }
1058
1059 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1060 'm','p',0 };
1061 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1062 'm','p',0 };
1063 static BYTE serialNum[] = { 1 };
1064 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1065 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1066
1067 static void test_signed_msg_open(void)
1068 {
1069 HCRYPTMSG msg;
1070 BOOL ret;
1071 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1072 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1073 CERT_INFO certInfo = { 0 };
1074
1075 SetLastError(0xdeadbeef);
1076 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1077 NULL, NULL);
1078 ok(!msg && GetLastError() == E_INVALIDARG,
1079 "Expected E_INVALIDARG, got %x\n", GetLastError());
1080 signInfo.cbSize = sizeof(signInfo);
1081 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1082 NULL, NULL);
1083 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1084 CryptMsgClose(msg);
1085
1086 signInfo.cSigners = 1;
1087 signInfo.rgSigners = &signer;
1088 /* With signer.pCertInfo unset, attempting to open this message this
1089 * crashes.
1090 */
1091 signer.pCertInfo = &certInfo;
1092 /* The cert info must contain a serial number and an issuer. */
1093 SetLastError(0xdeadbeef);
1094 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1095 NULL, NULL);
1096 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1097 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1098 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1099 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1100 GetLastError());
1101
1102 certInfo.SerialNumber.cbData = sizeof(serialNum);
1103 certInfo.SerialNumber.pbData = serialNum;
1104 SetLastError(0xdeadbeef);
1105 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1106 NULL, NULL);
1107 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1108 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1109 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1110 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1111 GetLastError());
1112
1113 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1114 certInfo.Issuer.pbData = encodedCommonName;
1115 SetLastError(0xdeadbeef);
1116 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1117 NULL, NULL);
1118 ok(!msg && (GetLastError() == E_INVALIDARG ||
1119 GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1120 "Expected E_INVALIDARG or CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1121
1122 /* The signer's hCryptProv must be set to something. Whether it's usable
1123 * or not will be checked after the hash algorithm is checked (see next
1124 * test.)
1125 */
1126 signer.hCryptProv = 1;
1127 SetLastError(0xdeadbeef);
1128 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1129 NULL, NULL);
1130 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1131 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1132 /* The signer's hash algorithm must also be set. */
1133 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1134 SetLastError(0xdeadbeef);
1135 /* Crashes in advapi32 in wine, don't do it */
1136 if (0) {
1137 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1138 &signInfo, NULL, NULL);
1139 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1140 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1141 }
1142 /* The signer's hCryptProv must also be valid. */
1143 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1144 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1145 if (!ret && GetLastError() == NTE_EXISTS) {
1146 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1147 PROV_RSA_FULL, 0);
1148 }
1149 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1150
1151 if (ret) {
1152 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1153 NULL, NULL);
1154 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1155 CryptMsgClose(msg);
1156 }
1157
1158 /* pCertInfo must still be set, but can be empty if the SignerId's issuer
1159 * and serial number are set.
1160 */
1161 certInfo.Issuer.cbData = 0;
1162 certInfo.SerialNumber.cbData = 0;
1163 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1164 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1165 sizeof(encodedCommonName);
1166 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1167 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1168 sizeof(serialNum);
1169 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1170 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1171 NULL, NULL);
1172 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1173 CryptMsgClose(msg);
1174
1175 CryptReleaseContext(signer.hCryptProv, 0);
1176 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1177 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1178 }
1179
1180 static const BYTE privKey[] = {
1181 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1182 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1183 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1184 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1185 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1186 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1187 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1188 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1189 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1190 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1191 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1192 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1193 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1194 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1195 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1196 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1197 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1198 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1199 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1200 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1201 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1202 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1203 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1204 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1205 static BYTE pubKey[] = {
1206 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1207 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1208 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1209 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1210 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1211
1212 static void test_signed_msg_update(void)
1213 {
1214 HCRYPTMSG msg;
1215 BOOL ret;
1216 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1217 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1218 CERT_INFO certInfo = { 0 };
1219 HCRYPTKEY key;
1220
1221 certInfo.SerialNumber.cbData = sizeof(serialNum);
1222 certInfo.SerialNumber.pbData = serialNum;
1223 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1224 certInfo.Issuer.pbData = encodedCommonName;
1225 signer.pCertInfo = &certInfo;
1226 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1227 signInfo.cSigners = 1;
1228 signInfo.rgSigners = &signer;
1229
1230 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1231 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1232 if (!ret && GetLastError() == NTE_EXISTS) {
1233 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1234 PROV_RSA_FULL, 0);
1235 }
1236 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1237
1238 if (!ret) {
1239 skip("No context for tests\n");
1240 return;
1241 }
1242
1243 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1244 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1245 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1246 /* Detached CMSG_SIGNED allows non-final updates. */
1247 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1248 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1249 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1250 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1251 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1252 /* The final update requires a private key in the hCryptProv, in order to
1253 * generate the signature.
1254 */
1255 SetLastError(0xdeadbeef);
1256 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1257 ok(!ret &&
1258 (GetLastError() == NTE_BAD_KEYSET ||
1259 GetLastError() == NTE_NO_KEY ||
1260 broken(GetLastError() == ERROR_SUCCESS)), /* Some Win9x */
1261 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1262 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1263 0, 0, &key);
1264 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1265 /* The final update should be able to succeed now that a key exists, but
1266 * the previous (invalid) final update prevents it.
1267 */
1268 SetLastError(0xdeadbeef);
1269 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1270 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1271 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1272 CryptMsgClose(msg);
1273
1274 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1275 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1276 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1277 /* Detached CMSG_SIGNED allows non-final updates. */
1278 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1279 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1280 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1281 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1282 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1283 /* Now that the private key exists, the final update can succeed (even
1284 * with no data.)
1285 */
1286 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1287 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1288 /* But no updates are allowed after the final update. */
1289 SetLastError(0xdeadbeef);
1290 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1291 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1292 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1293 SetLastError(0xdeadbeef);
1294 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1295 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1296 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1297 CryptMsgClose(msg);
1298
1299 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1300 NULL, NULL);
1301 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1302 /* Non-detached messages don't allow non-final updates.. */
1303 SetLastError(0xdeadbeef);
1304 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1305 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1306 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1307 /* but they do allow final ones. */
1308 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1309 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1310 CryptMsgClose(msg);
1311 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1312 NULL, NULL);
1313 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1314 /* They also allow final updates with no data. */
1315 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1316 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1317 CryptMsgClose(msg);
1318
1319 CryptDestroyKey(key);
1320 CryptReleaseContext(signer.hCryptProv, 0);
1321 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1322 CRYPT_DELETEKEYSET);
1323 }
1324
1325 static const BYTE signedEmptyBareContent[] = {
1326 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1327 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1328 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1329 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1330 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1331 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1332 static const BYTE signedEmptyContent[] = {
1333 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1334 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1335 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1336 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1337 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1338 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1339 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1340 static const BYTE detachedSignedBareContent[] = {
1341 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1342 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1343 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1344 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1345 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1346 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1347 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1348 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1349 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1350 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1351 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1352 static const BYTE detachedSignedContent[] = {
1353 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1354 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1355 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1356 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1357 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1358 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1359 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1360 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1361 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1362 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1363 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1364 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1365 static const BYTE signedBareContent[] = {
1366 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1367 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1368 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1369 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1370 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1371 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1372 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1373 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1374 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1375 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1376 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1377 static const BYTE signedContent[] = {
1378 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1379 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1380 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1381 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1382 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1383 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1384 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1385 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1386 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1387 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1388 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1389 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1390 0x0d };
1391 static const BYTE signedHash[] = {
1392 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1393 0x2f };
1394 static const BYTE signedKeyIdEmptyContent[] = {
1395 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
1396 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1397 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
1398 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1399 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1400 static const BYTE signedEncodedSigner[] = {
1401 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1402 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1403 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1404 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1405 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1406 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1407 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1408 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1409 static const BYTE signedWithAuthAttrsBareContent[] = {
1410 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1411 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1412 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1413 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1414 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1415 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1416 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1417 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1418 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1419 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1420 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1421 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1422 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1423 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1424 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1425 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1426 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1427 0xff,0xc6,0x33,0x63,0x34 };
1428 static BYTE cert[] = {
1429 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1430 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1431 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1432 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1433 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1434 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1435 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1436 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1437 0xff,0x02,0x01,0x01 };
1438 static BYTE v1CertWithPubKey[] = {
1439 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1440 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1441 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1442 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1443 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1444 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1445 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1446 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1447 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1448 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1449 0x01,0x01 };
1450 static const BYTE signedWithCertEmptyBareContent[] = {
1451 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1452 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1453 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1454 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1455 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1456 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1457 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1458 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1459 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1460 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1461 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1462 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1463 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1464 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1465 static const BYTE signedWithCertBareContent[] = {
1466 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1467 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1468 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1469 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1470 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1471 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1472 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1473 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1474 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1475 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1476 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1477 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1478 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1479 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1480 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1481 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1482 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1483 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1484 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1485 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1486 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1487 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1488 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1489 0x30,0x30,0x30,0x30,0x5a };
1490 static const BYTE signedWithCrlEmptyBareContent[] = {
1491 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1492 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1493 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1494 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1495 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1496 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1497 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1498 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1499 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1500 static const BYTE signedWithCrlBareContent[] = {
1501 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1502 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1503 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1504 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1505 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1506 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1507 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1508 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1509 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1510 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1511 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1512 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1513 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1514 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1515 0xa8,0x0d };
1516 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1517 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1518 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1519 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1520 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1521 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1522 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1523 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1524 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1525 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1526 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1527 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1528 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1529 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1530 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1531 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1532 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1533 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1534 0x04,0x00 };
1535 static const BYTE signedWithCertAndCrlBareContent[] = {
1536 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1537 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1538 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1539 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1540 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1541 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1542 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1543 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1544 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1545 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1546 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1547 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1548 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1549 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1550 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1551 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1552 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1553 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1554 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1555 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1556 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1557 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1558 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1559 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1560 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1561 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1562 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1563 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1564 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1565 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1566 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1567 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1568 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1569 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1570 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1571 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1572 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1573 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1574 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1575 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1576 static BYTE v1CertWithValidPubKey[] = {
1577 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1578 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1579 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1580 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1581 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1582 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1583 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1584 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1585 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1586 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1587 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1588 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1589 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1590 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1591 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1592 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1593 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1594 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1595 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1596 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1597 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1598 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1599 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1600 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1601 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1602 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1603 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1604 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1605 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1606 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1607 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1608 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1609 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1610 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1611 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1612 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1613 0x00 };
1614 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1615 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1616 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1617 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1618 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1619 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1620 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1621 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1622 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1623 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1624 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1625 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1626 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1627 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1628 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1629 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1630 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1631 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1632 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1633 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1634 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1635 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1636 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1637 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1638 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1639 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1640 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1641 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1642
1643 static void test_signed_msg_encoding(void)
1644 {
1645 HCRYPTMSG msg;
1646 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1647 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1648 CERT_INFO certInfo = { 0 };
1649 CERT_BLOB encodedCert = { sizeof(cert), cert };
1650 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1651 char oid_common_name[] = szOID_COMMON_NAME;
1652 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1653 encodedCommonName };
1654 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1655 BOOL ret;
1656 HCRYPTKEY key;
1657 DWORD size;
1658
1659 certInfo.SerialNumber.cbData = sizeof(serialNum);
1660 certInfo.SerialNumber.pbData = serialNum;
1661 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1662 certInfo.Issuer.pbData = encodedCommonName;
1663 signer.pCertInfo = &certInfo;
1664 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1665 signInfo.cSigners = 1;
1666 signInfo.rgSigners = &signer;
1667
1668 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1669 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1670 if (!ret && GetLastError() == NTE_EXISTS) {
1671 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1672 PROV_RSA_FULL, 0);
1673 }
1674 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1675
1676 if (!ret) {
1677 skip("No context for tests\n");
1678 return;
1679 }
1680
1681 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1682 0, 0, &key);
1683 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1684
1685 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1686 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1687 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1688
1689 check_param("detached signed empty bare content", msg,
1690 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1691 sizeof(signedEmptyBareContent));
1692 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1693 signedEmptyContent, sizeof(signedEmptyContent));
1694 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1695 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1696 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1697 signedHash, sizeof(signedHash));
1698 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1699 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1700 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1701 detachedSignedContent, sizeof(detachedSignedContent));
1702 SetLastError(0xdeadbeef);
1703 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1704 ok(!ret && (GetLastError() == CRYPT_E_INVALID_INDEX ||
1705 broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */)),
1706 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1707 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1708 signedEncodedSigner, sizeof(signedEncodedSigner));
1709
1710 CryptMsgClose(msg);
1711
1712 certInfo.SerialNumber.cbData = 0;
1713 certInfo.Issuer.cbData = 0;
1714 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1715 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1716 U(signer.SignerId).KeyId.pbData = serialNum;
1717 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1718 NULL, NULL);
1719 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1720 check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM,
1721 signedKeyIdEmptyContent, sizeof(signedKeyIdEmptyContent));
1722 CryptMsgClose(msg);
1723
1724 certInfo.SerialNumber.cbData = sizeof(serialNum);
1725 certInfo.SerialNumber.pbData = serialNum;
1726 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1727 certInfo.Issuer.pbData = encodedCommonName;
1728 signer.SignerId.dwIdChoice = 0;
1729 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1730 NULL, NULL);
1731 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1732
1733 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1734 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1735 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1736 signedEmptyContent, sizeof(signedEmptyContent));
1737 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1738 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1739 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1740 signedBareContent, sizeof(signedBareContent));
1741 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1742 signedContent, sizeof(signedContent));
1743
1744 CryptMsgClose(msg);
1745
1746 signer.cAuthAttr = 1;
1747 signer.rgAuthAttr = &attr;
1748 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1749 NULL, NULL);
1750 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1751
1752 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1753 check_param("signed with auth attrs bare content", msg,
1754 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1755 sizeof(signedWithAuthAttrsBareContent));
1756
1757 CryptMsgClose(msg);
1758
1759 signer.cAuthAttr = 0;
1760 signInfo.rgCertEncoded = &encodedCert;
1761 signInfo.cCertEncoded = 1;
1762 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1763 NULL, NULL);
1764 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1765
1766 check_param("signed with cert empty bare content", msg,
1767 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1768 sizeof(signedWithCertEmptyBareContent));
1769 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1770 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1771 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1772 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1773
1774 CryptMsgClose(msg);
1775
1776 signInfo.cCertEncoded = 0;
1777 signInfo.rgCrlEncoded = &encodedCrl;
1778 signInfo.cCrlEncoded = 1;
1779 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1780 NULL, NULL);
1781 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1782
1783 check_param("signed with crl empty bare content", msg,
1784 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1785 sizeof(signedWithCrlEmptyBareContent));
1786 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1787 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1788 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1789 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1790
1791 CryptMsgClose(msg);
1792
1793 signInfo.cCertEncoded = 1;
1794 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1795 NULL, NULL);
1796 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1797
1798 check_param("signed with cert and crl empty bare content", msg,
1799 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1800 sizeof(signedWithCertAndCrlEmptyBareContent));
1801 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1802 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1803 check_param("signed with cert and crl bare content", msg,
1804 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1805 sizeof(signedWithCertAndCrlBareContent));
1806
1807 CryptMsgClose(msg);
1808
1809 /* Test with a cert with a (bogus) public key */
1810 signInfo.cCrlEncoded = 0;
1811 encodedCert.cbData = sizeof(v1CertWithPubKey);
1812 encodedCert.pbData = v1CertWithPubKey;
1813 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1814 NULL, NULL);
1815 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1816 check_param("signedWithCertWithPubKeyBareContent", msg,
1817 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1818 sizeof(signedWithCertWithPubKeyBareContent));
1819 CryptMsgClose(msg);
1820
1821 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1822 encodedCert.pbData = v1CertWithValidPubKey;
1823 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1824 NULL, NULL);
1825 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1826 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1827 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1828 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1829 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1830 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1831 check_param("signedWithCertWithValidPubKeyContent", msg,
1832 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1833 sizeof(signedWithCertWithValidPubKeyContent));
1834 CryptMsgClose(msg);
1835
1836 CryptDestroyKey(key);
1837 CryptReleaseContext(signer.hCryptProv, 0);
1838 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1839 CRYPT_DELETEKEYSET);
1840 }
1841
1842 static void test_signed_msg_get_param(void)
1843 {
1844 BOOL ret;
1845 HCRYPTMSG msg;
1846 DWORD size, value = 0;
1847 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1848 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1849 CERT_INFO certInfo = { 0 };
1850
1851 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1852 NULL, NULL);
1853 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1854
1855 /* Content and bare content are always gettable */
1856 size = 0;
1857 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1858 ok(ret || broken(!ret /* Win9x */), "CryptMsgGetParam failed: %08x\n",
1859 GetLastError());
1860 if (!ret)
1861 {
1862 skip("message parameters are broken, skipping tests\n");
1863 return;
1864 }
1865 size = 0;
1866 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1867 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1868 /* For "signed" messages, so is the version. */
1869 size = 0;
1870 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1871 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1872 size = sizeof(value);
1873 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1874 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1875 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1876 /* But for this message, with no signers, the hash and signer aren't
1877 * available.
1878 */
1879 size = 0;
1880 SetLastError(0xdeadbeef);
1881 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1882 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1883 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1884 SetLastError(0xdeadbeef);
1885 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1886 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1887 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1888 /* As usual, the type isn't available. */
1889 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1890 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1891 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1892
1893 CryptMsgClose(msg);
1894
1895 certInfo.SerialNumber.cbData = sizeof(serialNum);
1896 certInfo.SerialNumber.pbData = serialNum;
1897 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1898 certInfo.Issuer.pbData = encodedCommonName;
1899 signer.pCertInfo = &certInfo;
1900 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1901 signInfo.cSigners = 1;
1902 signInfo.rgSigners = &signer;
1903
1904 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1905 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1906 if (!ret && GetLastError() == NTE_EXISTS) {
1907 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1908 PROV_RSA_FULL, 0);
1909 }
1910 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1911
1912 if (!ret) {
1913 skip("No context for tests\n");
1914 return;
1915 }
1916
1917 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1918 NULL, NULL);
1919 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1920
1921 /* This message, with one signer, has the hash and signer for index 0
1922 * available, but not for other indexes.
1923 */
1924 size = 0;
1925 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1926 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1927 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1928 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1929 size = 0;
1930 SetLastError(0xdeadbeef);
1931 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1932 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1933 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1934 SetLastError(0xdeadbeef);
1935 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1936 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1937 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1938 /* As usual, the type isn't available. */
1939 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1940 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1941 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1942
1943 CryptMsgClose(msg);
1944
1945 /* Opening the message using the CMS fields.. */
1946 certInfo.SerialNumber.cbData = 0;
1947 certInfo.Issuer.cbData = 0;
1948 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1949 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1950 sizeof(encodedCommonName);
1951 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1952 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1953 sizeof(serialNum);
1954 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1955 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1956 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1957 if (!ret && GetLastError() == NTE_EXISTS)
1958 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1959 PROV_RSA_FULL, 0);
1960 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1961 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1962 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1963 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1964 /* still results in the version being 1 when the issuer and serial number
1965 * are used and no additional CMS fields are used.
1966 */
1967 size = sizeof(value);
1968 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1969 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE),
1970 "CryptMsgGetParam failed: %08x\n", GetLastError());
1971 if (ret)
1972 ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value);
1973 /* Apparently the encoded signer can be retrieved.. */
1974 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1975 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1976 /* but the signer info, CMS signer info, and cert ID can't be. */
1977 SetLastError(0xdeadbeef);
1978 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1979 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1980 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1981 SetLastError(0xdeadbeef);
1982 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1983 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1984 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1985 SetLastError(0xdeadbeef);
1986 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1987 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1988 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1989 CryptMsgClose(msg);
1990
1991 /* Using the KeyId field of the SignerId results in the version becoming
1992 * the CMS version.
1993 */
1994 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1995 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1996 U(signer.SignerId).KeyId.pbData = serialNum;
1997 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1998 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1999 if (!ret && GetLastError() == NTE_EXISTS)
2000 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
2001 PROV_RSA_FULL, 0);
2002 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
2003 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
2004 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
2005 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
2006 size = sizeof(value);
2007 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
2008 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2009 if (ret)
2010 ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value);
2011 /* Even for a CMS message, the signer can be retrieved.. */
2012 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
2013 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2014 /* but the signer info, CMS signer info, and cert ID can't be. */
2015 SetLastError(0xdeadbeef);
2016 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2017 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2018 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2019 SetLastError(0xdeadbeef);
2020 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2021 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2022 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2023 SetLastError(0xdeadbeef);
2024 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
2025 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2026 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2027 CryptMsgClose(msg);
2028
2029 CryptReleaseContext(signer.hCryptProv, 0);
2030 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
2031 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2032 }
2033
2034 static void test_signed_msg(void)
2035 {
2036 test_signed_msg_open();
2037 test_signed_msg_update();
2038 test_signed_msg_encoding();
2039 test_signed_msg_get_param();
2040 }
2041
2042 static char oid_rsa_rc4[] = szOID_RSA_RC4;
2043
2044 static void test_enveloped_msg_open(void)
2045 {
2046 HCRYPTMSG msg;
2047 BOOL ret;
2048 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { 0 };
2049 PCCERT_CONTEXT context;
2050
2051 SetLastError(0xdeadbeef);
2052 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2053 &envelopedInfo, NULL, NULL);
2054 ok(!msg && GetLastError() == E_INVALIDARG,
2055 "expected E_INVALIDARG, got %08x\n", GetLastError());
2056
2057 envelopedInfo.cbSize = sizeof(envelopedInfo);
2058 SetLastError(0xdeadbeef);
2059 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2060 &envelopedInfo, NULL, NULL);
2061 ok(!msg &&
2062 (GetLastError() == CRYPT_E_UNKNOWN_ALGO ||
2063 GetLastError() == E_INVALIDARG), /* Win9x */
2064 "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", GetLastError());
2065
2066 envelopedInfo.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4;
2067 SetLastError(0xdeadbeef);
2068 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2069 &envelopedInfo, NULL, NULL);
2070 ok(msg != NULL ||
2071 broken(!msg), /* Win9x */
2072 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2073 CryptMsgClose(msg);
2074
2075 envelopedInfo.cRecipients = 1;
2076 if (!old_crypt32)
2077 {
2078 SetLastError(0xdeadbeef);
2079 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2080 &envelopedInfo, NULL, NULL);
2081 ok(!msg && GetLastError() == E_INVALIDARG,
2082 "expected E_INVALIDARG, got %08x\n", GetLastError());
2083 }
2084
2085 context = CertCreateCertificateContext(X509_ASN_ENCODING,
2086 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
2087 if (context)
2088 {
2089 envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo;
2090 SetLastError(0xdeadbeef);
2091 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2092 &envelopedInfo, NULL, NULL);
2093 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2094 CryptMsgClose(msg);
2095 SetLastError(0xdeadbeef);
2096 ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL,
2097 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
2098 ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
2099 SetLastError(0xdeadbeef);
2100 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2101 &envelopedInfo, NULL, NULL);
2102 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2103 CryptMsgClose(msg);
2104 CryptReleaseContext(envelopedInfo.hCryptProv, 0);
2105 CertFreeCertificateContext(context);
2106 }
2107 else
2108 win_skip("failed to create certificate context, skipping tests\n");
2109 }
2110
2111 static void test_enveloped_msg_update(void)
2112 {
2113 HCRYPTMSG msg;
2114 BOOL ret;
2115 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2116 { oid_rsa_rc4, { 0, NULL } }, NULL };
2117 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
2118
2119 SetLastError(0xdeadbeef);
2120 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2121 &envelopedInfo, NULL, NULL);
2122 ok(msg != NULL ||
2123 broken(!msg), /* Win9x */
2124 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2125 if (msg)
2126 {
2127 SetLastError(0xdeadbeef);
2128 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2129 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2130 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2131 SetLastError(0xdeadbeef);
2132 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2133 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2134 SetLastError(0xdeadbeef);
2135 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2136 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2137 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2138 CryptMsgClose(msg);
2139 }
2140 SetLastError(0xdeadbeef);
2141 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2142 &envelopedInfo, NULL, NULL);
2143 ok(msg != NULL ||
2144 broken(!msg), /* Win9x */
2145 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2146 if (msg)
2147 {
2148 SetLastError(0xdeadbeef);
2149 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2150 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2151 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2152 SetLastError(0xdeadbeef);
2153 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2154 ok(ret ||
2155 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2156 "CryptMsgUpdate failed: %08x\n", GetLastError());
2157 SetLastError(0xdeadbeef);
2158 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2159 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2160 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2161 CryptMsgClose(msg);
2162 }
2163 SetLastError(0xdeadbeef);
2164 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2165 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2166 ok(msg != NULL ||
2167 broken(!msg), /* Win9x */
2168 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2169 if (msg)
2170 {
2171 SetLastError(0xdeadbeef);
2172 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2173 ok(!ret && GetLastError() == E_INVALIDARG,
2174 "expected E_INVALIDARG, got %08x\n", GetLastError());
2175 SetLastError(0xdeadbeef);
2176 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2177 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2178 CryptMsgClose(msg);
2179 }
2180 SetLastError(0xdeadbeef);
2181 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2182 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2183 ok(msg != NULL ||
2184 broken(!msg), /* Win9x */
2185 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2186 if (msg)
2187 {
2188 SetLastError(0xdeadbeef);
2189 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2190 ok(!ret && GetLastError() == E_INVALIDARG,
2191 "expected E_INVALIDARG, got %08x\n", GetLastError());
2192 SetLastError(0xdeadbeef);
2193 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2194 ok(ret ||
2195 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2196 "CryptMsgUpdate failed: %08x\n", GetLastError());
2197 CryptMsgClose(msg);
2198 }
2199 SetLastError(0xdeadbeef);
2200 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2201 &envelopedInfo, NULL, &streamInfo);
2202 ok(msg != NULL ||
2203 broken(!msg), /* Win9x */
2204 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2205 if (msg)
2206 {
2207 SetLastError(0xdeadbeef);
2208 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2209 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2210 SetLastError(0xdeadbeef);
2211 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2212 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2213 CryptMsgClose(msg);
2214 }
2215 SetLastError(0xdeadbeef);
2216 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2217 &envelopedInfo, NULL, &streamInfo);
2218 ok(msg != NULL ||
2219 broken(!msg), /* Win9x */
2220 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2221 if (msg)
2222 {
2223 SetLastError(0xdeadbeef);
2224 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2225 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2226 SetLastError(0xdeadbeef);
2227 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2228 ok(ret ||
2229 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2230 "CryptMsgUpdate failed: %08x\n", GetLastError());
2231 CryptMsgClose(msg);
2232 }
2233 }
2234
2235 static const BYTE envelopedEmptyBareContent[] = {
2236 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2237 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2238 0x03,0x04,0x05,0x00,0x80,0x00 };
2239 static const BYTE envelopedEmptyContent[] = {
2240 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24,
2241 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2242 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2243 0x03,0x04,0x05,0x00,0x80,0x00 };
2244
2245 static void test_enveloped_msg_encoding(void)
2246 {
2247 HCRYPTMSG msg;
2248 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2249 { oid_rsa_rc4, { 0, NULL } }, NULL };
2250
2251 SetLastError(0xdeadbeef);
2252 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2253 &envelopedInfo, NULL, NULL);
2254 ok(msg != NULL ||
2255 broken(!msg), /* Win9x */
2256 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2257 if (msg)
2258 {
2259 check_param("enveloped empty bare content", msg,
2260 CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent,
2261 sizeof(envelopedEmptyBareContent));
2262 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
2263 envelopedEmptyContent, sizeof(envelopedEmptyContent));
2264 CryptMsgClose(msg);
2265 }
2266 }
2267
2268 static void test_enveloped_msg(void)
2269 {
2270 test_enveloped_msg_open();
2271 test_enveloped_msg_update();
2272 test_enveloped_msg_encoding();
2273 }
2274
2275 static CRYPT_DATA_BLOB b4 = { 0, NULL };
2276 static const struct update_accum a4 = { 1, &b4 };
2277
2278 static const BYTE bogusOIDContent[] = {
2279 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2280 0x04,0x00 };
2281 static const BYTE bogusHashContent[] = {
2282 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2283 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2284 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2285 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2286 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2287 static const BYTE envelopedBareContentWithoutData[] = {
2288 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2289 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2290 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2291 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2292 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b,
2293 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f,
2294 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94,
2295 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72,
2296 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18,
2297 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3,
2298 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6,
2299 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49,
2300 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e,
2301 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2302 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 };
2303
2304 static void test_decode_msg_update(void)
2305 {
2306 HCRYPTMSG msg;
2307 BOOL ret;
2308 CMSG_STREAM_INFO streamInfo = { 0 };
2309 DWORD i;
2310 struct update_accum accum = { 0, NULL };
2311
2312 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2313 /* Update with a full message in a final update */
2314 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2315 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2316 /* Can't update after a final update */
2317 SetLastError(0xdeadbeef);
2318 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2319 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2320 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2321 CryptMsgClose(msg);
2322
2323 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2324 /* Can't send a non-final update without streaming */
2325 SetLastError(0xdeadbeef);
2326 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2327 FALSE);
2328 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2329 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2330 /* A subsequent final update succeeds */
2331 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2332 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2333 CryptMsgClose(msg);
2334
2335 if (!old_crypt32)
2336 {
2337 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2338 /* Updating a message that has a NULL stream callback fails */
2339 SetLastError(0xdeadbeef);
2340 /* Crashes on some Win9x */
2341 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2342 FALSE);
2343 todo_wine
2344 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2345 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2346 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2347 GetLastError());
2348 /* Changing the callback pointer after the fact yields the same error (so
2349 * the message must copy the stream info, not just store a pointer to it)
2350 */
2351 streamInfo.pfnStreamOutput = nop_stream_output;
2352 SetLastError(0xdeadbeef);
2353 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2354 FALSE);
2355 todo_wine
2356 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2357 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2358 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2359 GetLastError());
2360 CryptMsgClose(msg);
2361 }
2362
2363 /* Empty non-final updates are allowed when streaming.. */
2364 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2365 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2366 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2367 /* but final updates aren't when not enough data has been received. */
2368 SetLastError(0xdeadbeef);
2369 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2370 todo_wine
2371 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2372 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2373 CryptMsgClose(msg);
2374
2375 /* Updating the message byte by byte is legal */
2376 streamInfo.pfnStreamOutput = accumulating_stream_output;
2377 streamInfo.pvArg = &accum;
2378 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2379 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2380 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2381 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2382 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2383 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2384 CryptMsgClose(msg);
2385 todo_wine
2386 check_updates("byte-by-byte empty content", &a4, &accum);
2387 free_updates(&accum);
2388
2389 /* Decoding bogus content fails in non-streaming mode.. */
2390 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2391 SetLastError(0xdeadbeef);
2392 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2393 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2394 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2395 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2396 GetLastError());
2397 CryptMsgClose(msg);
2398 /* and as the final update in streaming mode.. */
2399 streamInfo.pfnStreamOutput = nop_stream_output;
2400 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2401 SetLastError(0xdeadbeef);
2402 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2403 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2404 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2405 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2406 GetLastError());
2407 CryptMsgClose(msg);
2408 /* and even as a non-final update in streaming mode. */
2409 streamInfo.pfnStreamOutput = nop_stream_output;
2410 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2411 SetLastError(0xdeadbeef);
2412 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2413 todo_wine
2414 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2415 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2416 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2417 GetLastError());
2418 CryptMsgClose(msg);
2419
2420 /* An empty message can be opened with undetermined type.. */
2421 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2422 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2423 TRUE);
2424 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2425 CryptMsgClose(msg);
2426 /* but decoding it as an explicitly typed message fails. */
2427 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2428 NULL);
2429 SetLastError(0xdeadbeef);
2430 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2431 TRUE);
2432 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2433 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2434 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2435 GetLastError());
2436 CryptMsgClose(msg);
2437 /* On the other hand, decoding the bare content of an empty message fails
2438 * with unspecified type..
2439 */
2440 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2441 SetLastError(0xdeadbeef);
2442 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2443 sizeof(dataEmptyBareContent), TRUE);
2444 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2445 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2446 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2447 GetLastError());
2448 CryptMsgClose(msg);
2449 /* but succeeds with explicit type. */
2450 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2451 NULL);
2452 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2453 sizeof(dataEmptyBareContent), TRUE);
2454 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2455 CryptMsgClose(msg);
2456
2457 /* Decoding valid content with an unsupported OID fails */
2458 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2459 SetLastError(0xdeadbeef);
2460 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2461 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2462 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2463 CryptMsgClose(msg);
2464
2465 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2466 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2467 SetLastError(0xdeadbeef);
2468 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2469 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2470 "CryptMsgUpdate failed: %08x\n", GetLastError());
2471 CryptMsgClose(msg);
2472 /* while with specified type it fails. */
2473 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2474 NULL);
2475 SetLastError(0xdeadbeef);
2476 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2477 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2478 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2479 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2480 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2481 GetLastError());
2482 CryptMsgClose(msg);
2483 /* On the other hand, decoding the bare content of an empty hash message
2484 * fails with unspecified type..
2485 */
2486 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2487 SetLastError(0xdeadbeef);
2488 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2489 sizeof(hashEmptyBareContent), TRUE);
2490 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2491 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2492 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2493 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2494 GetLastError());
2495 CryptMsgClose(msg);
2496 /* but succeeds with explicit type. */
2497 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2498 NULL);
2499 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2500 sizeof(hashEmptyBareContent), TRUE);
2501 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2502 "CryptMsgUpdate failed: %x\n", GetLastError());
2503 CryptMsgClose(msg);
2504
2505 /* And again, opening a (non-empty) hash message with unspecified type
2506 * succeeds..
2507 */
2508 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2509 SetLastError(0xdeadbeef);
2510 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2511 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2512 CryptMsgClose(msg);
2513 /* while with specified type it fails.. */
2514 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2515 NULL);
2516 SetLastError(0xdeadbeef);
2517 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2518 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2519 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2520 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2521 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2522 GetLastError());
2523 CryptMsgClose(msg);
2524 /* and decoding the bare content of a non-empty hash message fails with
2525 * unspecified type..
2526 */
2527 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2528 SetLastError(0xdeadbeef);
2529 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2530 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2531 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2532 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2533 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2534 GetLastError());
2535 CryptMsgClose(msg);
2536 /* but succeeds with explicit type. */
2537 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2538 NULL);
2539 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2540 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2541 CryptMsgClose(msg);
2542
2543 /* Opening a (non-empty) hash message with unspecified type and a bogus
2544 * hash value succeeds..
2545 */
2546 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2547 SetLastError(0xdeadbeef);
2548 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2549 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2550 CryptMsgClose(msg);
2551
2552 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2553 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2554 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2555 CryptMsgClose(msg);
2556 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2557 SetLastError(0xdeadbeef);
2558 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2559 sizeof(signedWithCertAndCrlBareContent), TRUE);
2560 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2561 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2562 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2563 GetLastError());
2564 CryptMsgClose(msg);
2565 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2566 NULL);
2567 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2568 sizeof(signedWithCertAndCrlBareContent), TRUE);
2569 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2570 CryptMsgClose(msg);
2571
2572 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2573 NULL, NULL);
2574 /* The first update succeeds.. */
2575 ret = CryptMsgUpdate(msg, detachedSignedContent,
2576 sizeof(detachedSignedContent), TRUE);
2577 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2578 /* as does a second (probably to update the detached portion).. */
2579 ret = CryptMsgUpdate(msg, detachedSignedContent,
2580 sizeof(detachedSignedContent), TRUE);
2581 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2582 /* while a third fails. */
2583 ret = CryptMsgUpdate(msg, detachedSignedContent,
2584 sizeof(detachedSignedContent), TRUE);
2585 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2586 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2587 CryptMsgClose(msg);
2588
2589 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2590 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2591 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2592 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2593 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2594 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2595 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2596 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2597 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2598
2599 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2600 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2601 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2602 CryptMsgClose(msg);
2603
2604 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2605 NULL);
2606 SetLastError(0xdeadbeef);
2607 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2608 sizeof(envelopedEmptyBareContent), TRUE);
2609 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2610 CryptMsgClose(msg);
2611
2612 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2613 NULL);
2614 SetLastError(0xdeadbeef);
2615 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2616 sizeof(envelopedEmptyContent), TRUE);
2617 ok(!ret &&
2618 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2619 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2620 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2621 CryptMsgClose(msg);
2622
2623 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2624 SetLastError(0xdeadbeef);
2625 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2626 sizeof(envelopedEmptyBareContent), TRUE);
2627 ok(!ret &&
2628 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2629 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2630 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2631 CryptMsgClose(msg);
2632
2633 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2634 SetLastError(0xdeadbeef);
2635 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2636 sizeof(envelopedEmptyContent), TRUE);
2637 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2638 CryptMsgClose(msg);
2639
2640 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2641 NULL);
2642 SetLastError(0xdeadbeef);
2643 ret = CryptMsgUpdate(msg, envelopedBareContentWithoutData,
2644 sizeof(envelopedBareContentWithoutData), TRUE);
2645 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2646 CryptMsgClose(msg);
2647 }
2648
2649 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2650 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2651
2652 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2653 const CMSG_SIGNER_INFO *expected)
2654 {
2655 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2656 expected->dwVersion, got->dwVersion);
2657 ok(got->Issuer.cbData == expected->Issuer.cbData,
2658 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2659 got->Issuer.cbData);
2660 ok(!memcmp(got->Issuer.pbData, expected->Issuer.pbData, got->Issuer.cbData),
2661 "Unexpected issuer\n");
2662 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2663 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2664 got->SerialNumber.cbData);
2665 ok(!memcmp(got->SerialNumber.pbData, expected->SerialNumber.pbData,
2666 got->SerialNumber.cbData), "Unexpected serial number\n");
2667 /* FIXME: check more things */
2668 }
2669
2670 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2671 const CMSG_CMS_SIGNER_INFO *expected)
2672 {
2673 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2674 expected->dwVersion, got->dwVersion);
2675 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2676 "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2677 got->SignerId.dwIdChoice);
2678 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2679 {
2680 if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2681 {
2682 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2683 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2684 "Expected issuer size %d, got %d\n",
2685 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2686 U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2687 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2688 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2689 U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2690 "Unexpected issuer\n");
2691 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2692 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2693 "Expected serial number size %d, got %d\n",
2694 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2695 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2696 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2697 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2698 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2699 "Unexpected serial number\n");
2700 }
2701 else
2702 {
2703 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2704 "expected key id size %d, got %d\n",
2705 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2706 ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2707 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2708 "unexpected key id\n");
2709 }
2710 }
2711 /* FIXME: check more things */
2712 }
2713
2714 static const BYTE signedWithCertAndCrlComputedHash[] = {
2715 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2716 0x2f };
2717 static BYTE keyIdIssuer[] = {
2718 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2719 0x0a,0x07,0x01,0x04,0x01,0x01 };
2720 static const BYTE publicPrivateKeyPair[] = {
2721 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00,
2722 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b,
2723 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50,
2724 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54,
2725 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39,
2726 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7,
2727 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48,
2728 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17,
2729 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54,
2730 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33,
2731 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52,
2732 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e,
2733 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61,
2734 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb,
2735 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02,
2736 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90,
2737 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e,
2738 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce,
2739 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14,
2740 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5,
2741 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5,
2742 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94,
2743 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68,
2744 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71,
2745 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25,
2746 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc,
2747 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a,
2748 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64,
2749 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77,
2750 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68,
2751 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab,
2752 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9,
2753 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed,
2754 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01,
2755 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e,
2756 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71,
2757 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0,
2758 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87,
2759 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b,
2760 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e };
2761 static const BYTE envelopedMessage[] = {
2762 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,
2763 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,
2764 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,
2765 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,
2766 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
2767 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65,
2768 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae,
2769 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1,
2770 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51,
2771 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf,
2772 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b,
2773 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e,
2774 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e,
2775 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70,
2776 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,
2777 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,
2778 0x04,0x5f,0x80,0xf2,0x17 };
2779 static const BYTE envelopedBareMessage[] = {
2780 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2781 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2782 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2783 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2784 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d,
2785 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d,
2786 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5,
2787 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e,
2788 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2,
2789 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4,
2790 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70,
2791 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c,
2792 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55,
2793 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2794 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c,
2795 0x2d,0xa3,0x6e };
2796 static const BYTE envelopedMessageWith3Recps[] = {
2797 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,
2798 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e,
2799 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,
2800 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,
2801 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,
2802 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e,
2803 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba,
2804 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f,
2805 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5,
2806 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21,
2807 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae,
2808 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0,
2809 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96,
2810 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae,
2811 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,
2812 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,
2813 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6,
2814 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
2815 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf,
2816 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9,
2817 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3,
2818 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02,
2819 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70,
2820 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3,
2821 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74,
2822 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94,
2823 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7,
2824 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,
2825 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,
2826 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
2827 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98,
2828 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5,
2829 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9,
2830 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3,
2831 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8,
2832 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac,
2833 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc,
2834 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5,
2835 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1,
2836 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
2837 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,
2838 0x80,0x04,0x4e,0x99,0x9d,0x4c };
2839 static const BYTE serialNumber[] = {
2840 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2,
2841 0x1c };
2842 static const BYTE issuer[] = {
2843 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 };
2844
2845 static void test_decode_msg_get_param(void)
2846 {
2847 HCRYPTMSG msg;
2848 HCRYPTPROV hCryptProv;
2849 HCRYPTKEY key = 0;
2850 BOOL ret;
2851 DWORD size = 0, value;
2852 LPBYTE buf;
2853 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2854
2855 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2856 SetLastError(0xdeadbeef);
2857 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2858 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2859 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2860 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2861 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2862 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2863 sizeof(msgData));
2864 CryptMsgClose(msg);
2865
2866 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2867 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2868 if (ret)
2869 {
2870 /* Crashes on some Win9x */
2871 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2872 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2873 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2874 emptyHashParam, sizeof(emptyHashParam));
2875 }
2876 CryptMsgClose(msg);
2877 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2878 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2879 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2880 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2881 sizeof(msgData));
2882 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2883 sizeof(hashParam));
2884 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2885 hashParam, sizeof(hashParam));
2886 /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2887 * even though there's only one hash.
2888 */
2889 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2890 ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2891 "CryptMsgGetParam failed: %08x\n", GetLastError());
2892 if (ret)
2893 buf = CryptMemAlloc(size);
2894 else
2895 buf = NULL;
2896 if (buf)
2897 {
2898 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2899 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2900 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2901 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2902 CryptMemFree(buf);
2903 }
2904 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2905 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2906 value = CMSG_HASHED_DATA_V0;
2907 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2908 sizeof(value));
2909 CryptMsgClose(msg);
2910
2911 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2912 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2913 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2914 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2915 sizeof(msgData));
2916 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2917 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2918 size = sizeof(value);
2919 value = 2112;
2920 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2921 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2922 ok(value == 1, "Expected 1 signer, got %d\n", value);
2923 size = 0;
2924 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2925 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2926 "CryptMsgGetParam failed: %08x\n", GetLastError());
2927 if (ret)
2928 buf = CryptMemAlloc(size);
2929 else
2930 buf = NULL;
2931 if (buf)
2932 {
2933 CMSG_SIGNER_INFO signer = { 0 };
2934
2935 signer.dwVersion = 1;
2936 signer.Issuer.cbData = sizeof(encodedCommonName);
2937 signer.Issuer.pbData = encodedCommonName;
2938 signer.SerialNumber.cbData = sizeof(serialNum);
2939 signer.SerialNumber.pbData = serialNum;
2940 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2941 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2942 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2943 CryptMemFree(buf);
2944 }
2945 /* Getting the CMS signer info of a PKCS7 message is possible. */
2946 size = 0;
2947 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2948 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2949 "CryptMsgGetParam failed: %08x\n", GetLastError());
2950 if (ret)
2951 buf = CryptMemAlloc(size);
2952 else
2953 buf = NULL;
2954 if (buf)
2955 {
2956 CMSG_CMS_SIGNER_INFO signer = { 0 };
2957
2958 signer.dwVersion = 1;
2959 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2960 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2961 sizeof(encodedCommonName);
2962 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2963 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2964 sizeof(serialNum);
2965 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2966 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2967 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2968 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2969 CryptMemFree(buf);
2970 }
2971 /* index is ignored when getting signer count */
2972 size = sizeof(value);
2973 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2974 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2975 ok(value == 1, "Expected 1 signer, got %d\n", value);
2976 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2977 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2978 ok(value == 0, "Expected 0 certs, got %d\n", value);
2979 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2980 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2981 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2982 CryptMsgClose(msg);
2983 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2984 NULL);
2985 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2986 sizeof(signedWithCertAndCrlBareContent), TRUE);
2987 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2988 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2989 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2990 ok(value == 1, "Expected 1 cert, got %d\n", value);
2991 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2992 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2993 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2994 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2995 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2996 check_param("signed with cert and CRL computed hash", msg,
2997 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2998 sizeof(signedWithCertAndCrlComputedHash));
2999 CryptMsgClose(msg);
3000
3001 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3002 ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
3003 sizeof(signedKeyIdEmptyContent), TRUE);
3004 if (!ret && GetLastError() == OSS_DATA_ERROR)
3005 {
3006 CryptMsgClose(msg);
3007 win_skip("Subsequent tests crash on some Win9x\n");
3008 return;
3009 }
3010 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3011 size = sizeof(value);
3012 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
3013 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3014 ok(value == 1, "Expected 1 signer, got %d\n", value);
3015 /* Getting the regular (non-CMS) signer info from a CMS message is also
3016 * possible..
3017 */
3018 size = 0;
3019 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
3020 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3021 if (ret)
3022 buf = CryptMemAlloc(size);
3023 else
3024 buf = NULL;
3025 if (buf)
3026 {
3027 CMSG_SIGNER_INFO signer;
3028 BYTE zero = 0;
3029
3030 /* and here's the little oddity: for a CMS message using the key id
3031 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
3032 * a signer with a zero (not empty) serial number, and whose issuer is
3033 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
3034 * and value of the key id.
3035 */
3036 signer.dwVersion = CMSG_SIGNED_DATA_V3;
3037 signer.Issuer.cbData = sizeof(keyIdIssuer);
3038 signer.Issuer.pbData = keyIdIssuer;
3039 signer.SerialNumber.cbData = 1;
3040 signer.SerialNumber.pbData = &zero;
3041 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
3042 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
3043 CryptMemFree(buf);
3044 }
3045 size = 0;
3046 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
3047 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3048 if (ret)
3049 buf = CryptMemAlloc(size);
3050 else
3051 buf = NULL;
3052 if (buf)
3053 {
3054 CMSG_CMS_SIGNER_INFO signer = { 0 };
3055
3056 signer.dwVersion = CMSG_SIGNED_DATA_V3;
3057 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
3058 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
3059 U(signer.SignerId).KeyId.pbData = serialNum;
3060 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3061 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
3062 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
3063 CryptMemFree(buf);
3064 }
3065 CryptMsgClose(msg);
3066
3067 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3068 NULL);
3069 CryptMsgUpdate(msg, envelopedEmptyBareContent,
3070 sizeof(envelopedEmptyBareContent), TRUE);
3071 check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL,
3072 0);
3073 CryptMsgClose(msg);
3074
3075 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3076 CryptMsgUpdate(msg, envelopedEmptyContent, sizeof(envelopedEmptyContent),
3077 TRUE);
3078 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0);
3079 CryptMsgClose(msg);
3080
3081 pCryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL,
3082 CRYPT_VERIFYCONTEXT);
3083 SetLastError(0xdeadbeef);
3084 ret = CryptImportKey(hCryptProv, publicPrivateKeyPair,
3085 sizeof(publicPrivateKeyPair), 0, 0, &key);
3086 ok(ret ||
3087 broken(!ret && GetLastError() == NTE_PERM), /* WinME and some NT4 */
3088 "CryptImportKey failed: %08x\n", GetLastError());
3089
3090 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3091 CryptMsgUpdate(msg, envelopedMessage, sizeof(envelopedMessage), TRUE);
3092 check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM,
3093 envelopedMessage + sizeof(envelopedMessage) - 4, 4);
3094 if (key)
3095 {
3096 decryptPara.hCryptProv = hCryptProv;
3097 SetLastError(0xdeadbeef);
3098 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3099 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3100 decryptPara.hCryptProv = 0;
3101 SetLastError(0xdeadbeef);
3102 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3103 ok(!ret && GetLastError() == CRYPT_E_ALREADY_DECRYPTED,
3104 "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError());
3105 check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData,
3106 sizeof(msgData));
3107 }
3108 else
3109 win_skip("failed to import a key, skipping tests\n");
3110 CryptMsgClose(msg);
3111
3112 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3113 NULL);
3114 CryptMsgUpdate(msg, envelopedBareMessage, sizeof(envelopedBareMessage),
3115 TRUE);
3116 check_param("enveloped bare message before decrypting", msg,
3117 CMSG_CONTENT_PARAM, envelopedBareMessage +
3118 sizeof(envelopedBareMessage) - 4, 4);
3119 if (key)
3120 {
3121 decryptPara.hCryptProv = hCryptProv;
3122 SetLastError(0xdeadbeef);
3123 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3124 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3125 check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData,
3126 sizeof(msgData));
3127 }
3128 else
3129 win_skip("failed to import a key, skipping tests\n");
3130 CryptMsgClose(msg);
3131
3132 if (key)
3133 CryptDestroyKey(key);
3134 CryptReleaseContext(hCryptProv, 0);
3135
3136 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3137 CryptMsgUpdate(msg, envelopedMessageWith3Recps,
3138 sizeof(envelopedMessageWith3Recps), TRUE);
3139 value = 3;
3140 check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM,
3141 (const BYTE *)&value, sizeof(value));
3142 size = 0;
3143 SetLastError(0xdeadbeef);
3144 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 3, NULL, &size);
3145 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3146 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3147 size = 0;
3148 SetLastError(0xdeadbeef);
3149 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, NULL, &size);
3150 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3151 ok(size >= 142, "unexpected size: %u\n", size);
3152 if (ret)
3153 buf = CryptMemAlloc(size);
3154 else
3155 buf = NULL;
3156 if (buf)
3157 {
3158 CERT_INFO *certInfo = (CERT_INFO *)buf;
3159
3160 SetLastError(0xdeadbeef);
3161 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, buf, &size);
3162 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3163 ok(certInfo->SerialNumber.cbData == sizeof(serialNumber),
3164 "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData);
3165 ok(!memcmp(certInfo->SerialNumber.pbData, serialNumber,
3166 sizeof(serialNumber)), "unexpected serial number\n");
3167 ok(certInfo->Issuer.cbData == sizeof(issuer),
3168 "unexpected issuer size: %u\n", certInfo->Issuer.cbData);
3169 ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)),
3170 "unexpected issuer\n");
3171 CryptMemFree(buf);
3172 }
3173 CryptMsgClose(msg);
3174 }
3175
3176 static void test_decode_msg(void)
3177 {
3178 test_decode_msg_update();
3179 test_decode_msg_get_param();
3180 }
3181
3182 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
3183 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
3184 static BYTE encodedPubKey[] = {
3185 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
3186 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
3187 0x0d,0x0e,0x0f };
3188 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
3189 static BYTE mod_encoded[] = {
3190 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
3191 0x01,0x00,0x01 };
3192
3193 static void test_msg_control(void)
3194 {
3195 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3196 BOOL ret;
3197 HCRYPTMSG msg;
3198 DWORD i;
3199 CERT_INFO certInfo = { 0 };
3200 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
3201 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
3202 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
3203
3204 /* Crashes
3205 ret = CryptMsgControl(NULL, 0, 0, NULL);
3206 */
3207
3208 /* Data encode messages don't allow any sort of control.. */
3209 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
3210 NULL);
3211 /* either with no prior update.. */
3212 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3213 {
3214 SetLastError(0xdeadbeef);
3215 ret = CryptMsgControl(msg, 0, i, NULL);
3216 ok(!ret && GetLastError() == E_INVALIDARG,
3217 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3218 }
3219 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3220 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3221 /* or after an update. */
3222 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3223 {
3224 SetLastError(0xdeadbeef);
3225 ret = CryptMsgControl(msg, 0, i, NULL);
3226 ok(!ret && GetLastError() == E_INVALIDARG,
3227 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3228 }
3229 CryptMsgClose(msg);
3230
3231 /* Hash encode messages don't allow any sort of control.. */
3232 hashInfo.cbSize = sizeof(hashInfo);
3233 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
3234 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
3235 NULL, NULL);
3236 /* either with no prior update.. */
3237 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3238 {
3239 SetLastError(0xdeadbeef);
3240 ret = CryptMsgControl(msg, 0, i, NULL);
3241 ok(!ret && GetLastError() == E_INVALIDARG,
3242 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3243 }
3244 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3245 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3246 /* or after an update. */
3247 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3248 {
3249 SetLastError(0xdeadbeef);
3250 ret = CryptMsgControl(msg, 0, i, NULL);
3251 ok(!ret && GetLastError() == E_INVALIDARG,
3252 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3253 }
3254 CryptMsgClose(msg);
3255
3256 /* Signed encode messages likewise don't allow any sort of control.. */
3257 signInfo.cbSize = sizeof(signInfo);
3258 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
3259 NULL, NULL);
3260 /* either before an update.. */
3261 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3262 {
3263 SetLastError(0xdeadbeef);
3264 ret = CryptMsgControl(msg, 0, i, NULL);
3265 ok(!ret && GetLastError() == E_INVALIDARG,
3266 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3267 }
3268 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3269 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3270 /* or after an update. */
3271 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3272 {
3273 SetLastError(0xdeadbeef);
3274 ret = CryptMsgControl(msg, 0, i, NULL);
3275 ok(!ret && GetLastError() == E_INVALIDARG,
3276 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3277 }
3278 CryptMsgClose(msg);
3279
3280 /* Decode messages behave a bit differently. */
3281 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3282 /* Bad control type */
3283 SetLastError(0xdeadbeef);
3284 ret = CryptMsgControl(msg, 0, 0, NULL);
3285 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3286 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3287 SetLastError(0xdeadbeef);
3288 ret = CryptMsgControl(msg, 1, 0, NULL);
3289 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3290 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3291 /* Can't verify the hash of an indeterminate-type message */
3292 SetLastError(0xdeadbeef);
3293 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3294 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3295 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3296 /* Crashes
3297 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
3298 */
3299 /* Can't decrypt an indeterminate-type message */
3300 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3301 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3302 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3303 CryptMsgClose(msg);
3304
3305 if (!old_crypt32)
3306 {
3307 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3308 NULL);
3309 /* Can't verify the hash of an empty message */
3310 SetLastError(0xdeadbeef);
3311 /* Crashes on some Win9x */
3312 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3313 todo_wine
3314 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3315 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3316 /* Crashes
3317 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3318 */
3319 /* Can't verify the signature of a hash message */
3320 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3321 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3322 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3323 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
3324 TRUE);
3325 /* Oddly enough, this fails, crashes on some Win9x */
3326 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3327 ok(!ret, "Expected failure\n");
3328 CryptMsgClose(msg);
3329 }
3330 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3331 NULL);
3332 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
3333 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3334 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3335 /* Can't decrypt an indeterminate-type message */
3336 SetLastError(0xdeadbeef);
3337 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3338 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3339 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3340 CryptMsgClose(msg);
3341
3342 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3343 NULL, NULL);
3344 /* Can't verify the hash of a detached message before it's been updated. */
3345 SetLastError(0xdeadbeef);
3346 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3347 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3348 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3349 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3350 TRUE);
3351 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3352 /* Still can't verify the hash of a detached message with the content
3353 * of the detached hash given..
3354 */
3355 SetLastError(0xdeadbeef);
3356 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3357 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
3358 "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
3359 /* and giving the content of the message after attempting to verify the
3360 * hash fails.
3361 */
3362 SetLastError(0xdeadbeef);
3363 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3364 todo_wine
3365 ok(!ret &&
3366 (GetLastError() == NTE_BAD_HASH_STATE ||
3367 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3368 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
3369 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3370 "got %08x\n", GetLastError());
3371 CryptMsgClose(msg);
3372
3373 /* Finally, verifying the hash of a detached message in the correct order:
3374 * 1. Update with the detached hash message
3375 * 2. Update with the content of the message
3376 * 3. Verifying the hash of the message
3377 * succeeds.
3378 */
3379 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3380 NULL, NULL);
3381 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3382 TRUE);
3383 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3384 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3385 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3386 SetLastError(0xdeadbeef);
3387 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3388 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3389 CryptMsgClose(msg);
3390
3391 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3392 NULL);
3393 /* Can't verify the hash of a signed message */
3394 SetLastError(0xdeadbeef);
3395 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3396 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3397 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3398 /* Can't decrypt a signed message */
3399 SetLastError(0xdeadbeef);
3400 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3401 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3402 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3403 /* Crash
3404 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3405 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3406 */
3407 CryptMsgUpdate(msg, signedWithCertBareContent,
3408 sizeof(signedWithCertBareContent), TRUE);
3409 /* With an empty cert info, the signer can't be found in the message (and
3410 * the signature can't be verified.
3411 */
3412 SetLastError(0xdeadbeef);
3413 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3414 ok(!ret && (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND ||
3415 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3416 "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n",
3417 GetLastError());
3418 /* The cert info is expected to have an issuer, serial number, and public
3419 * key info set.
3420 */
3421 certInfo.SerialNumber.cbData = sizeof(serialNum);
3422 certInfo.SerialNumber.pbData = serialNum;
3423 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3424 certInfo.Issuer.pbData = encodedCommonName;
3425 SetLastError(0xdeadbeef);
3426 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3427 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3428 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3429 "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError());
3430 CryptMsgClose(msg);
3431 /* This cert has a public key, but it's not in a usable form */
3432 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3433 NULL);
3434 ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
3435 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
3436 if (ret)
3437 {
3438 /* Crashes on some Win9x */
3439 /* Again, cert info needs to have a public key set */
3440 SetLastError(0xdeadbeef);
3441 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3442 ok(!ret &&
3443 (GetLastError() == CRYPT_E_ASN1_EOD ||
3444 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3445 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3446 /* The public key is supposed to be in encoded form.. */
3447 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3448 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3449 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
3450 SetLastError(0xdeadbeef);
3451 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3452 ok(!ret &&
3453 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3454 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3455 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3456 /* but not as a X509_PUBLIC_KEY_INFO.. */
3457 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3458 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
3459 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
3460 SetLastError(0xdeadbeef);
3461 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3462 ok(!ret &&
3463 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3464 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3465 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3466 /* This decodes successfully, but it doesn't match any key in the message */
3467 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
3468 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
3469 SetLastError(0xdeadbeef);
3470 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3471 /* In Wine's rsaenh, this fails to decode because the key length is too
3472 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
3473 * now.
3474 */
3475 todo_wine
3476 ok(!ret &&
3477 (GetLastError() == NTE_BAD_SIGNATURE ||
3478 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3479 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3480 }
3481 CryptMsgClose(msg);
3482 /* A message with no data doesn't have a valid signature */
3483 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3484 ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
3485 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
3486 if (ret)
3487 {
3488 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3489 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
3490 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
3491 SetLastError(0xdeadbeef);
3492 /* Crashes on some Win9x */
3493 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3494 ok(!ret &&
3495 (GetLastError() == NTE_BAD_SIGNATURE ||
3496 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3497 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3498 }
3499 CryptMsgClose(msg);
3500 /* Finally, this succeeds */
3501 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3502 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3503 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3504 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3505 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3506 "CryptMsgControl failed: %08x\n", GetLastError());
3507 CryptMsgClose(msg);
3508
3509 /* Test verifying signature of a detached signed message */
3510 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3511 NULL, NULL);
3512 ret = CryptMsgUpdate(msg, detachedSignedContent,
3513 sizeof(detachedSignedContent), TRUE);
3514 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3515 /* Can't verify the sig without having updated the data */
3516 SetLastError(0xdeadbeef);
3517 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3518 ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
3519 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3520 "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n",
3521 GetLastError());
3522 /* Now that the signature's been checked, can't do the final update */
3523 SetLastError(0xdeadbeef);
3524 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3525 todo_wine
3526 ok((!ret &&
3527 (GetLastError() == NTE_BAD_HASH_STATE ||
3528 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3529 GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */
3530 broken(ret), /* Win9x */
3531 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3532 "got %08x\n", GetLastError());
3533 CryptMsgClose(msg);
3534 /* Updating with the detached portion of the message and the data of the
3535 * the message allows the sig to be verified.
3536 */
3537 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3538 NULL, NULL);
3539 ret = CryptMsgUpdate(msg, detachedSignedContent,
3540 sizeof(detachedSignedContent), TRUE);
3541 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3542 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3543 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3544 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3545 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3546 "CryptMsgControl failed: %08x\n", GetLastError());
3547 CryptMsgClose(msg);
3548
3549 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3550 NULL);
3551 decryptPara.cbSize = 0;
3552 SetLastError(0xdeadbeef);
3553 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3554 ok(!ret && GetLastError() == E_INVALIDARG,
3555 "expected E_INVALIDARG, got %08x\n", GetLastError());
3556 decryptPara.cbSize = sizeof(decryptPara);
3557 if (!old_crypt32)
3558 {
3559 SetLastError(0xdeadbeef);
3560 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3561 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3562 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3563 }
3564 SetLastError(0xdeadbeef);
3565 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
3566 sizeof(envelopedEmptyBareContent), TRUE);
3567 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3568 SetLastError(0xdeadbeef);
3569 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3570 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3571 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3572 CryptMsgClose(msg);
3573
3574 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3575 NULL);
3576 SetLastError(0xdeadbeef);
3577 ret = CryptMsgUpdate(msg, envelopedBareMessage,
3578 sizeof(envelopedBareMessage), TRUE);
3579 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3580 SetLastError(0xdeadbeef);
3581 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3582 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
3583 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
3584 CryptMsgClose(msg);
3585 }
3586
3587 /* win9x has much less parameter checks and will crash on many tests
3588 * this code is from test_signed_msg_update()
3589 */
3590 static BOOL detect_nt(void)
3591 {
3592 BOOL ret;
3593 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
3594 CERT_INFO certInfo = { 0 };
3595
3596 if (!pCryptAcquireContextW)
3597 return FALSE;
3598
3599 certInfo.SerialNumber.cbData = sizeof(serialNum);
3600 certInfo.SerialNumber.pbData = serialNum;
3601 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3602 certInfo.Issuer.pbData = encodedCommonName;
3603 signer.pCertInfo = &certInfo;
3604 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3605
3606 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3607 PROV_RSA_FULL, CRYPT_NEWKEYSET);
3608 if (!ret && GetLastError() == NTE_EXISTS) {
3609 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3610 PROV_RSA_FULL, 0);
3611 }
3612
3613 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
3614
3615 /* cleanup */
3616 CryptReleaseContext(signer.hCryptProv, 0);
3617 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
3618 CRYPT_DELETEKEYSET);
3619
3620 return TRUE;
3621 }
3622
3623 static void test_msg_get_and_verify_signer(void)
3624 {
3625 BOOL ret;
3626 HCRYPTMSG msg;
3627 PCCERT_CONTEXT signer;
3628 DWORD signerIndex;
3629 HCERTSTORE store;
3630
3631 /* Crash */
3632 if (0)
3633 {
3634 CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
3635 CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3636 }
3637
3638 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3639 /* An empty message has no signer */
3640 SetLastError(0xdeadbeef);
3641 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3642 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3643 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3644 /* The signer is cleared on error */
3645 signer = (PCCERT_CONTEXT)0xdeadbeef;
3646 SetLastError(0xdeadbeef);
3647 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3648 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3649 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3650 ok(!signer, "expected signer to be NULL\n");
3651 /* The signer index is also cleared on error */
3652 signerIndex = 0xdeadbeef;
3653 SetLastError(0xdeadbeef);
3654 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3655 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3656 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3657 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
3658 /* An unsigned message (msgData isn't a signed message at all)
3659 * likewise has no signer.
3660 */
3661 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3662 SetLastError(0xdeadbeef);
3663 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3664 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3665 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3666 CryptMsgClose(msg);
3667
3668 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3669 /* A "signed" message created with no signer cert likewise has no signer */
3670 ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
3671 if (ret)
3672 {
3673 /* Crashes on most Win9x */
3674 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3675 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3676 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3677 }
3678 CryptMsgClose(msg);
3679
3680 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3681 /* A signed message succeeds, .. */
3682 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3683 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3684 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3685 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3686 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3687 /* the signer index can be retrieved, .. */
3688 signerIndex = 0xdeadbeef;
3689 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3690 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3691 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3692 if (ret)
3693 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
3694 /* as can the signer cert. */
3695 signer = (PCCERT_CONTEXT)0xdeadbeef;
3696 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3697 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3698 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3699 if (ret)
3700 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3701 "expected a valid signer\n");
3702 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3703 CertFreeCertificateContext(signer);
3704 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3705 */
3706 signerIndex = 0xdeadbeef;
3707 SetLastError(0xdeadbeef);
3708 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3709 NULL, &signerIndex);
3710 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3711 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3712 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3713 * message signer not to be found.
3714 */
3715 SetLastError(0xdeadbeef);
3716 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3717 NULL, NULL);
3718 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3719 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3720 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3721 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3722 * the message signer not to be found.
3723 */
3724 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3725 CERT_STORE_CREATE_NEW_FLAG, NULL);
3726 SetLastError(0xdeadbeef);
3727 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3728 NULL, NULL);
3729 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3730 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3731 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3732 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3733 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3734 CERT_STORE_ADD_ALWAYS, NULL);
3735 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win98 */),
3736 "CertAddEncodedCertificateToStore failed: 0x%08x\n", GetLastError());
3737 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3738 * the signer succeeds.
3739 */
3740 SetLastError(0xdeadbeef);
3741 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3742 NULL, NULL);
3743 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3744 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3745 CertCloseStore(store, 0);
3746 CryptMsgClose(msg);
3747 }
3748
3749 START_TEST(msg)
3750 {
3751 init_function_pointers();
3752 have_nt = detect_nt();
3753 if (!have_nt)
3754 win_skip("Win9x crashes on some parameter checks\n");
3755
3756 /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
3757 if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
3758 {
3759 win_skip("Some tests will crash on older crypt32 implementations\n");
3760 old_crypt32 = TRUE;
3761 }
3762
3763 /* Basic parameter checking tests */
3764 test_msg_open_to_encode();
3765 test_msg_open_to_decode();
3766 test_msg_get_param();
3767 test_msg_close();
3768 test_msg_control();
3769
3770 /* Message-type specific tests */
3771 test_data_msg();
3772 test_hash_msg();
3773 test_signed_msg();
3774 test_enveloped_msg();
3775 test_decode_msg();
3776
3777 test_msg_get_and_verify_signer();
3778 }