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