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
28 #include "wine/test.h"
30 static char oid_rsa_md5[] = szOID_RSA_MD5;
32 static BOOL (WINAPI * pCryptAcquireContextW)
33 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
35 static void init_function_pointers(void)
37 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
39 #define GET_PROC(dll, func) \
40 p ## func = (void *)GetProcAddress(dll, #func); \
42 trace("GetProcAddress(%s) failed\n", #func);
44 GET_PROC(hAdvapi32, CryptAcquireContextW)
49 static void test_msg_open_to_encode(void)
54 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
56 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
58 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
63 SetLastError(0xdeadbeef);
64 msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
65 ok(!msg && GetLastError() == E_INVALIDARG,
66 "Expected E_INVALIDARG, got %x\n", GetLastError());
67 SetLastError(0xdeadbeef);
68 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
69 ok(!msg && GetLastError() == E_INVALIDARG,
70 "Expected E_INVALIDARG, got %x\n", GetLastError());
72 /* Bad message types */
73 SetLastError(0xdeadbeef);
74 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
75 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
76 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
77 SetLastError(0xdeadbeef);
78 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
80 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
81 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
82 SetLastError(0xdeadbeef);
83 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
84 CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
85 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
86 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
87 SetLastError(0xdeadbeef);
88 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
90 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
91 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
94 static void test_msg_open_to_decode(void)
97 CMSG_STREAM_INFO streamInfo = { 0 };
99 SetLastError(0xdeadbeef);
100 msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
101 ok(!msg && GetLastError() == E_INVALIDARG,
102 "Expected E_INVALIDARG, got %x\n", GetLastError());
105 SetLastError(0xdeadbeef);
106 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
107 ok(!msg && GetLastError() == E_INVALIDARG,
108 "Expected E_INVALIDARG, got %x\n", GetLastError());
109 SetLastError(0xdeadbeef);
110 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
111 ok(!msg && GetLastError() == E_INVALIDARG,
112 "Expected E_INVALIDARG, got %x\n", GetLastError());
114 /* The message type can be explicit... */
115 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
117 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
119 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
121 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
123 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
125 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
127 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
129 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
131 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
132 CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
133 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
136 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
137 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
139 /* or even invalid. */
140 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
142 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
144 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
145 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
148 /* And even though the stream info parameter "must be set to NULL" for
149 * CMSG_HASHED, it's still accepted.
151 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
153 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
157 static void test_msg_get_param(void)
161 DWORD size, i, value;
162 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
163 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
166 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
167 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
168 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
171 /* Decoded messages */
172 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
173 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
174 /* For decoded messages, the type is always available */
176 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
177 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
178 size = sizeof(value);
179 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
180 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
181 /* For this (empty) message, the type isn't set */
182 ok(value == 0, "Expected type 0, got %d\n", value);
185 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
187 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
188 /* For explicitly typed messages, the type is known. */
189 size = sizeof(value);
190 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
191 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
192 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
193 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
196 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
197 ok(!ret, "Parameter %d: expected failure\n", i);
201 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
203 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
204 size = sizeof(value);
205 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
206 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
207 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
208 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
211 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
212 ok(!ret, "Parameter %d: expected failure\n", i);
216 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
218 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
219 size = sizeof(value);
220 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
221 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
222 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
223 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
226 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
227 ok(!ret, "Parameter %d: expected failure\n", i);
231 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
233 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
234 size = sizeof(value);
235 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
236 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
237 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
238 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
241 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
242 ok(!ret, "Parameter %d: expected failure\n", i);
246 /* Explicitly typed messages get their types set, even if they're invalid */
247 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
249 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
250 size = sizeof(value);
251 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
252 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
253 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
256 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
257 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
258 size = sizeof(value);
259 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
260 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
261 ok(value == 1000, "Expected 1000, got %d\n", value);
265 static void test_msg_close(void)
270 /* NULL succeeds.. */
271 ret = CryptMsgClose(NULL);
272 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
273 /* but an arbitrary pointer crashes. */
275 ret = CryptMsgClose((HCRYPTMSG)1);
276 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
278 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
279 ret = CryptMsgClose(msg);
280 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
283 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
284 const BYTE *expected, DWORD expectedSize)
291 ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
292 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
293 buf = HeapAlloc(GetProcessHeap(), 0, size);
294 ret = CryptMsgGetParam(msg, param, 0, buf, &size);
295 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
296 ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
298 if (size == expectedSize && size)
299 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
300 HeapFree(GetProcessHeap(), 0, buf);
303 static void test_data_msg_open(void)
306 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
307 CMSG_STREAM_INFO streamInfo = { 0 };
308 char oid[] = "1.2.3";
310 /* The data message type takes no additional info */
311 SetLastError(0xdeadbeef);
312 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
314 ok(!msg && GetLastError() == E_INVALIDARG,
315 "Expected E_INVALIDARG, got %x\n", GetLastError());
316 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
318 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
321 /* An empty stream info is allowed. */
322 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
324 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
327 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
328 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
330 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
332 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
333 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
334 CMSG_DATA, NULL, oid, NULL);
335 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
337 /* and when a stream info is given, even though you're not supposed to be
338 * able to use anything but szOID_RSA_data when streaming is being used.
340 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
341 CMSG_DATA, NULL, oid, &streamInfo);
342 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
346 static const BYTE msgData[] = { 1, 2, 3, 4 };
348 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
354 static void test_data_msg_update(void)
358 CMSG_STREAM_INFO streamInfo = { 0 };
360 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
362 /* Can't update a message that wasn't opened detached with final = FALSE */
363 SetLastError(0xdeadbeef);
364 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
365 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
366 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
367 /* Updating it with final = TRUE succeeds */
368 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
369 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
370 /* Any subsequent update will fail, as the last was final */
371 SetLastError(0xdeadbeef);
372 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
373 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
374 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
377 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
379 /* Can't update a message with no data */
380 SetLastError(0xdeadbeef);
381 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
382 ok(!ret && GetLastError() == E_INVALIDARG,
383 "Expected E_INVALIDARG, got %x\n", GetLastError());
384 /* Curiously, a valid update will now fail as well, presumably because of
385 * the last (invalid, but final) update.
387 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
388 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
389 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
392 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
393 CMSG_DATA, NULL, NULL, NULL);
394 /* Doesn't appear to be able to update CMSG-DATA with non-final updates */
395 SetLastError(0xdeadbeef);
396 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
397 ok(!ret && GetLastError() == E_INVALIDARG,
398 "Expected E_INVALIDARG, got %x\n", GetLastError());
399 SetLastError(0xdeadbeef);
400 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
401 ok(!ret && GetLastError() == E_INVALIDARG,
402 "Expected E_INVALIDARG, got %x\n", GetLastError());
403 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
404 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
407 /* Calling update after opening with an empty stream info (with a bogus
408 * output function) yields an error:
410 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
412 SetLastError(0xdeadbeef);
413 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
414 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
415 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
417 /* Calling update with a valid output function succeeds, even if the data
418 * exceeds the size specified in the stream info.
420 streamInfo.pfnStreamOutput = nop_stream_output;
421 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
423 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
424 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
425 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
426 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
430 static void test_data_msg_get_param(void)
435 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
437 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
440 /* Content and bare content are always gettable when not streaming */
442 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
443 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
445 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
446 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
447 /* But for this type of message, the signer and hash aren't applicable,
448 * and the type isn't available.
451 SetLastError(0xdeadbeef);
452 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
453 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
454 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
455 SetLastError(0xdeadbeef);
456 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
457 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
458 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
459 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
460 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
461 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
464 /* Can't get content or bare content when streaming */
465 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
467 SetLastError(0xdeadbeef);
468 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
469 ok(!ret && GetLastError() == E_INVALIDARG,
470 "Expected E_INVALIDARG, got %x\n", GetLastError());
471 SetLastError(0xdeadbeef);
472 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
473 ok(!ret && GetLastError() == E_INVALIDARG,
474 "Expected E_INVALIDARG, got %x\n", GetLastError());
478 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
479 static const BYTE dataEmptyContent[] = {
480 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
482 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
483 static const BYTE dataContent[] = {
484 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
485 0x04,0x04,0x01,0x02,0x03,0x04 };
490 CRYPT_DATA_BLOB *updates;
493 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
494 DWORD cb, BOOL final)
496 struct update_accum *accum = (struct update_accum *)pvArg;
500 accum->updates = CryptMemRealloc(accum->updates,
501 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
503 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
506 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
508 blob->pbData = CryptMemAlloc(cb);
511 memcpy(blob->pbData, pb, cb);
520 /* The updates of a (bogus) definite-length encoded message */
521 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
522 0x07,0x01,0xa0,0x02,0x04,0x00 };
523 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
524 static CRYPT_DATA_BLOB b1[] = {
529 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
530 /* The updates of a definite-length encoded message */
531 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
532 0x07,0x01,0xa0,0x06,0x04,0x04 };
533 static CRYPT_DATA_BLOB b2[] = {
537 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
538 /* The updates of an indefinite-length encoded message */
539 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
540 0x07,0x01,0xa0,0x80,0x24,0x80 };
541 static BYTE u5[] = { 0x04,0x04 };
542 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
543 static CRYPT_DATA_BLOB b3[] = {
551 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
553 static void check_updates(LPCSTR header, const struct update_accum *expected,
554 const struct update_accum *got)
558 ok(expected->cUpdates == got->cUpdates,
559 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
561 if (expected->cUpdates == got->cUpdates)
562 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
564 ok(expected->updates[i].cbData == got->updates[i].cbData,
565 "%s, update %d: expected %d bytes, got %d\n", header, i,
566 expected->updates[i].cbData, got->updates[i].cbData);
567 if (expected->updates[i].cbData && expected->updates[i].cbData ==
568 got->updates[i].cbData)
569 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
570 got->updates[i].cbData), "%s, update %d: unexpected value\n",
575 /* Frees the updates stored in accum */
576 static void free_updates(struct update_accum *accum)
580 for (i = 0; i < accum->cUpdates; i++)
581 CryptMemFree(accum->updates[i].pbData);
582 CryptMemFree(accum->updates);
583 accum->updates = NULL;
587 static void test_data_msg_encoding(void)
591 static char oid[] = "1.2.3";
592 struct update_accum accum = { 0, NULL };
593 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
595 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
597 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
598 dataEmptyBareContent, sizeof(dataEmptyBareContent));
599 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
600 sizeof(dataEmptyContent));
601 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
602 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
603 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
604 dataBareContent, sizeof(dataBareContent));
605 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
606 sizeof(dataContent));
608 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
609 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
610 CMSG_DATA, NULL, NULL, NULL);
611 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
612 dataEmptyBareContent, sizeof(dataEmptyBareContent));
613 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
614 sizeof(dataEmptyContent));
615 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
616 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
617 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
618 dataBareContent, sizeof(dataBareContent));
619 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
620 sizeof(dataContent));
622 /* The inner OID is apparently ignored */
623 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
625 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
626 dataEmptyBareContent, sizeof(dataEmptyBareContent));
627 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
628 dataEmptyContent, sizeof(dataEmptyContent));
629 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
630 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
631 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
632 dataBareContent, sizeof(dataBareContent));
633 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
634 sizeof(dataContent));
636 /* A streaming message is DER encoded if the length is not 0xffffffff, but
637 * curiously, updates aren't validated to make sure they don't exceed the
638 * stated length. (The resulting output will of course fail to decode.)
640 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
642 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
643 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
645 check_updates("bogus data message with definite length", &a1, &accum);
646 free_updates(&accum);
647 /* A valid definite-length encoding: */
648 streamInfo.cbContent = sizeof(msgData);
649 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
651 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
653 check_updates("data message with definite length", &a2, &accum);
654 free_updates(&accum);
655 /* An indefinite-length encoding: */
656 streamInfo.cbContent = 0xffffffff;
657 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
659 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
660 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
663 check_updates("data message with indefinite length", &a3, &accum);
664 free_updates(&accum);
667 static void test_data_msg(void)
669 test_data_msg_open();
670 test_data_msg_update();
671 test_data_msg_get_param();
672 test_data_msg_encoding();
675 static void test_hash_msg_open(void)
678 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
679 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
681 SetLastError(0xdeadbeef);
682 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
684 ok(!msg && GetLastError() == E_INVALIDARG,
685 "Expected E_INVALIDARG, got %x\n", GetLastError());
686 hashInfo.cbSize = sizeof(hashInfo);
687 SetLastError(0xdeadbeef);
688 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
690 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
691 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
692 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
693 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
695 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
697 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
698 CMSG_HASHED, &hashInfo, NULL, NULL);
699 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
701 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
702 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
703 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
707 static void test_hash_msg_update(void)
711 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
712 { oid_rsa_md5, { 0, NULL } }, NULL };
713 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
715 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
716 CMSG_HASHED, &hashInfo, NULL, NULL);
717 /* Detached hashed messages opened in non-streaming mode allow non-final
720 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
721 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
722 /* including non-final updates with no data.. */
723 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
724 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
725 /* and final updates with no data. */
726 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
727 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
728 /* But no updates are allowed after the final update. */
729 SetLastError(0xdeadbeef);
730 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
731 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
732 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
733 SetLastError(0xdeadbeef);
734 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
735 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
736 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
738 /* Non-detached messages, in contrast, don't allow non-final updates in
739 * non-streaming mode.
741 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
743 SetLastError(0xdeadbeef);
744 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
745 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
746 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
747 /* Final updates (including empty ones) are allowed. */
748 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
749 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
751 /* And, of course, streaming mode allows non-final updates */
752 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
754 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
755 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
757 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
758 * to be a bug, it isn't actually used - see encoding tests.)
760 streamInfo.pfnStreamOutput = NULL;
761 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
763 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
764 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
768 static const BYTE emptyHashParam[] = {
769 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
772 static void test_hash_msg_get_param(void)
776 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
777 { oid_rsa_md5, { 0, NULL } }, NULL };
779 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
782 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
784 /* Content and bare content are always gettable for non-streamed messages */
786 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
787 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
789 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
790 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
791 /* The hash is also available. */
793 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
794 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
795 ok(size == sizeof(buf), "Unexpected size %d\n", size);
796 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
797 if (size == sizeof(buf))
798 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
799 /* By getting the hash, further updates are not allowed */
800 SetLastError(0xdeadbeef);
801 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
802 ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
803 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
804 /* The version is also available, and should be zero for this message. */
806 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
807 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
808 size = sizeof(value);
809 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
810 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
811 ok(value == 0, "Expected version 0, got %d\n", value);
812 /* As usual, the type isn't available. */
813 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
814 ok(!ret, "Expected failure\n");
817 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
819 /* Streamed messages don't allow you to get the content or bare content. */
820 SetLastError(0xdeadbeef);
821 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
822 ok(!ret && GetLastError() == E_INVALIDARG,
823 "Expected E_INVALIDARG, got %x\n", GetLastError());
824 SetLastError(0xdeadbeef);
825 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
826 ok(!ret && GetLastError() == E_INVALIDARG,
827 "Expected E_INVALIDARG, got %x\n", GetLastError());
828 /* The hash is still available. */
830 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
831 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
832 ok(size == sizeof(buf), "Unexpected size %d\n", size);
833 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
834 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
835 if (size == sizeof(buf))
836 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
837 /* After updating the hash, further updates aren't allowed on streamed
840 SetLastError(0xdeadbeef);
841 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
842 ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
843 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
847 static const BYTE hashEmptyBareContent[] = {
848 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
849 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
850 static const BYTE hashEmptyContent[] = {
851 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
852 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
853 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
854 static const BYTE hashBareContent[] = {
855 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
856 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
857 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
858 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
859 static const BYTE hashContent[] = {
860 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
861 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
862 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
863 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
864 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
866 static const BYTE detachedHashNonFinalBareContent[] = {
867 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
868 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
869 0x07,0x01,0x04,0x00 };
870 static const BYTE detachedHashNonFinalContent[] = {
871 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
872 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
873 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
874 0x07,0x01,0x04,0x00 };
875 static const BYTE detachedHashBareContent[] = {
876 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
877 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
878 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
879 0x9d,0x2a,0x8f,0x26,0x2f };
880 static const BYTE detachedHashContent[] = {
881 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
882 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
883 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
884 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
885 0x9d,0x2a,0x8f,0x26,0x2f };
887 static void test_hash_msg_encoding(void)
890 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
892 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
893 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
895 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
896 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
898 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
899 hashEmptyBareContent, sizeof(hashEmptyBareContent));
900 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
901 hashEmptyContent, sizeof(hashEmptyContent));
902 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
903 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
904 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
905 hashBareContent, sizeof(hashBareContent));
906 check_param("hash content", msg, CMSG_CONTENT_PARAM,
907 hashContent, sizeof(hashContent));
909 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
910 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
911 CMSG_HASHED, &hashInfo, NULL, NULL);
912 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
913 hashEmptyBareContent, sizeof(hashEmptyBareContent));
914 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
915 hashEmptyContent, sizeof(hashEmptyContent));
916 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
917 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
918 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
919 hashBareContent, sizeof(hashBareContent));
920 check_param("hash content", msg, CMSG_CONTENT_PARAM,
921 hashContent, sizeof(hashContent));
923 /* Same test, but with CMSG_DETACHED_FLAG set */
924 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
925 CMSG_HASHED, &hashInfo, NULL, NULL);
926 check_param("detached hash empty bare content", msg,
927 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
928 sizeof(hashEmptyBareContent));
929 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
930 hashEmptyContent, sizeof(hashEmptyContent));
931 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
932 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
933 check_param("detached hash not final bare content", msg,
934 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
935 sizeof(detachedHashNonFinalBareContent));
936 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
937 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
938 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
939 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
940 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
941 detachedHashBareContent, sizeof(detachedHashBareContent));
942 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
943 detachedHashContent, sizeof(detachedHashContent));
944 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
945 detachedHashBareContent, sizeof(detachedHashBareContent));
946 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
947 detachedHashContent, sizeof(detachedHashContent));
949 /* In what appears to be a bug, streamed updates to hash messages don't
950 * call the output function.
952 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
954 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
955 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
956 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
957 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
959 check_updates("empty hash message", &empty_accum, &accum);
960 free_updates(&accum);
962 streamInfo.cbContent = sizeof(msgData);
963 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
965 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
966 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
968 check_updates("hash message", &empty_accum, &accum);
969 free_updates(&accum);
971 streamInfo.cbContent = sizeof(msgData);
972 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
973 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
974 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
975 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
977 check_updates("detached hash message", &empty_accum, &accum);
978 free_updates(&accum);
981 static void test_hash_msg(void)
983 test_hash_msg_open();
984 test_hash_msg_update();
985 test_hash_msg_get_param();
986 test_hash_msg_encoding();
989 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
991 static BYTE serialNum[] = { 1 };
992 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
993 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
995 static void test_signed_msg_open(void)
999 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1000 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1001 CERT_INFO certInfo = { 0 };
1003 SetLastError(0xdeadbeef);
1004 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1006 ok(!msg && GetLastError() == E_INVALIDARG,
1007 "Expected E_INVALIDARG, got %x\n", GetLastError());
1008 signInfo.cbSize = sizeof(signInfo);
1009 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1011 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1014 signInfo.cSigners = 1;
1015 signInfo.rgSigners = &signer;
1016 /* With signer.pCertInfo unset, attempting to open this message this
1019 signer.pCertInfo = &certInfo;
1020 /* The cert info must contain a serial number and an issuer. */
1021 SetLastError(0xdeadbeef);
1022 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1024 ok(!msg && GetLastError() == E_INVALIDARG,
1025 "Expected E_INVALIDARG, got %x\n", GetLastError());
1026 certInfo.SerialNumber.cbData = sizeof(serialNum);
1027 certInfo.SerialNumber.pbData = serialNum;
1028 SetLastError(0xdeadbeef);
1029 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1031 ok(!msg && GetLastError() == E_INVALIDARG,
1032 "Expected E_INVALIDARG, got %x\n", GetLastError());
1033 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1034 certInfo.Issuer.pbData = encodedCommonName;
1035 SetLastError(0xdeadbeef);
1036 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1038 ok(!msg && GetLastError() == E_INVALIDARG,
1039 "Expected E_INVALIDARG, got %x\n", GetLastError());
1041 /* The signer's hCryptProv must be set to something. Whether it's usable
1042 * or not will be checked after the hash algorithm is checked (see next
1045 signer.hCryptProv = 1;
1046 SetLastError(0xdeadbeef);
1047 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1049 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1050 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1051 /* The signer's hash algorithm must also be set. */
1052 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1053 SetLastError(0xdeadbeef);
1054 /* Crashes in advapi32 in wine, don't do it */
1056 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1057 &signInfo, NULL, NULL);
1058 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1059 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1061 /* The signer's hCryptProv must also be valid. */
1062 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1063 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1064 if (!ret && GetLastError() == NTE_EXISTS)
1065 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1067 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1068 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1070 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1073 CryptReleaseContext(signer.hCryptProv, 0);
1074 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1075 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1078 static const BYTE privKey[] = {
1079 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1080 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1081 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1082 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1083 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1084 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1085 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1086 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1087 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1088 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1089 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1090 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1091 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1092 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1093 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1094 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1095 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1096 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1097 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1098 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1099 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1100 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1101 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1102 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1104 static void test_signed_msg_update(void)
1108 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1109 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1110 CERT_INFO certInfo = { 0 };
1113 certInfo.SerialNumber.cbData = sizeof(serialNum);
1114 certInfo.SerialNumber.pbData = serialNum;
1115 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1116 certInfo.Issuer.pbData = encodedCommonName;
1117 signer.pCertInfo = &certInfo;
1118 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1119 signInfo.cSigners = 1;
1120 signInfo.rgSigners = &signer;
1121 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1122 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1123 if (!ret && GetLastError() == NTE_EXISTS)
1124 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1126 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1127 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1128 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1129 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1130 /* Detached CMSG_SIGNED allows non-final updates. */
1131 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1132 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1133 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1134 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1135 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1136 /* The final update requires a private key in the hCryptProv, in order to
1137 * generate the signature.
1139 SetLastError(0xdeadbeef);
1140 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1141 ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1142 GetLastError() == NTE_NO_KEY),
1143 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1144 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1146 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1147 /* The final update should be able to succeed now that a key exists, but
1148 * the previous (invalid) final update prevents it.
1150 SetLastError(0xdeadbeef);
1151 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1152 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1153 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1156 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1157 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1158 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1159 /* Detached CMSG_SIGNED allows non-final updates. */
1160 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1161 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1162 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1163 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1164 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1165 /* Now that the private key exists, the final update can succeed (even
1168 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1169 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1170 /* But no updates are allowed after the final update. */
1171 SetLastError(0xdeadbeef);
1172 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1173 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1174 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1175 SetLastError(0xdeadbeef);
1176 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1177 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1178 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1181 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1183 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1184 /* Non-detached messages don't allow non-final updates.. */
1185 SetLastError(0xdeadbeef);
1186 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1187 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1188 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1189 /* but they do allow final ones. */
1190 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1191 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1193 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1195 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1196 /* They also allow final updates with no data. */
1197 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1198 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1201 CryptDestroyKey(key);
1202 CryptReleaseContext(signer.hCryptProv, 0);
1203 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1204 CRYPT_DELETEKEYSET);
1207 static const BYTE signedEmptyBareContent[] = {
1208 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1209 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1210 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1211 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1212 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1213 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1214 static const BYTE signedEmptyContent[] = {
1215 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1216 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1217 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1218 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1219 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1220 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1221 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1222 static const BYTE detachedSignedBareContent[] = {
1223 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1224 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1225 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1226 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1227 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1228 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1229 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1230 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1231 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1232 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1233 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1234 static const BYTE detachedSignedContent[] = {
1235 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1236 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1237 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1238 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1239 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1240 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1241 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1242 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1243 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1244 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1245 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1246 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1247 static const BYTE signedBareContent[] = {
1248 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1249 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1250 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1251 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1252 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1253 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1254 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1255 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1256 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1257 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1258 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1259 static const BYTE signedContent[] = {
1260 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1261 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1262 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1263 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1264 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1265 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1266 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1267 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1268 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1269 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1270 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1271 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1273 static const BYTE signedHash[] = {
1274 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1276 static const BYTE signedEncodedSigner[] = {
1277 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1278 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1279 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1280 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1281 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1282 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1283 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1284 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1285 static const BYTE signedWithAuthAttrsBareContent[] = {
1286 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1287 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1288 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1289 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1290 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1291 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1292 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1293 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1294 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1295 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1296 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1297 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1298 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1299 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1300 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1301 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1302 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1303 0xff,0xc6,0x33,0x63,0x34 };
1304 static BYTE cert[] = {
1305 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1306 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1307 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1308 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1309 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1310 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1311 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1312 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1313 0xff,0x02,0x01,0x01 };
1314 static BYTE v1CertWithPubKey[] = {
1315 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1316 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1317 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1318 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1319 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1320 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1321 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1322 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1323 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1324 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1326 static const BYTE signedWithCertEmptyBareContent[] = {
1327 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1328 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1329 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1330 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1331 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1332 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1333 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1334 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1335 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1336 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1337 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1338 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1339 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1340 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1341 static const BYTE signedWithCertBareContent[] = {
1342 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1343 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1344 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1345 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1346 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1347 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1348 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1349 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1350 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1351 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1352 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1353 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1354 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1355 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1356 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1357 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1358 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1359 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1360 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1361 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1362 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1363 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1364 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1365 0x30,0x30,0x30,0x30,0x5a };
1366 static const BYTE signedWithCrlEmptyBareContent[] = {
1367 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1368 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1369 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1370 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1371 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1372 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1373 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1374 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1375 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1376 static const BYTE signedWithCrlBareContent[] = {
1377 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1378 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1379 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1380 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1381 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1382 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1383 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1384 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1385 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1386 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1387 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1388 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1389 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1390 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1392 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1393 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1394 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1395 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1396 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1397 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1398 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1399 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1400 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1401 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1402 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1403 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1404 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1405 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1406 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1407 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1408 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1409 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1411 static const BYTE signedWithCertAndCrlBareContent[] = {
1412 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1413 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1414 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1415 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1416 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1417 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1418 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1419 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1420 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1421 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1422 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1423 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1424 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1425 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1426 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1427 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1428 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1429 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1430 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1431 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1432 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1433 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1434 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1435 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1436 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1437 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1438 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1439 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1440 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1441 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1442 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1443 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1444 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1445 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1446 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1447 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1448 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,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,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1451 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1453 static void test_signed_msg_encoding(void)
1456 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1457 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1458 CERT_INFO certInfo = { 0 };
1459 CERT_BLOB encodedCert = { sizeof(cert), cert };
1460 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1461 char oid_common_name[] = szOID_COMMON_NAME;
1462 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1463 encodedCommonName };
1464 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1469 certInfo.SerialNumber.cbData = sizeof(serialNum);
1470 certInfo.SerialNumber.pbData = serialNum;
1471 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1472 certInfo.Issuer.pbData = encodedCommonName;
1473 signer.pCertInfo = &certInfo;
1474 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1475 signInfo.cSigners = 1;
1476 signInfo.rgSigners = &signer;
1477 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1478 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1479 if (!ret && GetLastError() == NTE_EXISTS)
1480 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1482 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1483 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1485 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1487 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1488 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1489 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1491 check_param("detached signed empty bare content", msg,
1492 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1493 sizeof(signedEmptyBareContent));
1494 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1495 signedEmptyContent, sizeof(signedEmptyContent));
1496 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1497 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1498 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1499 signedHash, sizeof(signedHash));
1500 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1501 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1502 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1503 detachedSignedContent, sizeof(detachedSignedContent));
1504 SetLastError(0xdeadbeef);
1505 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1506 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1507 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1508 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1509 signedEncodedSigner, sizeof(signedEncodedSigner));
1513 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1515 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1517 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1518 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1519 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1520 signedEmptyContent, sizeof(signedEmptyContent));
1521 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1522 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1523 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1524 signedBareContent, sizeof(signedBareContent));
1525 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1526 signedContent, sizeof(signedContent));
1530 signer.cAuthAttr = 1;
1531 signer.rgAuthAttr = &attr;
1532 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1534 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1536 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1537 check_param("signed with auth attrs bare content", msg,
1538 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1539 sizeof(signedWithAuthAttrsBareContent));
1543 signer.cAuthAttr = 0;
1544 signInfo.rgCertEncoded = &encodedCert;
1545 signInfo.cCertEncoded = 1;
1546 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1548 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1550 check_param("signed with cert empty bare content", msg,
1551 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1552 sizeof(signedWithCertEmptyBareContent));
1553 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1554 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1555 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1556 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1560 signInfo.cCertEncoded = 0;
1561 signInfo.rgCrlEncoded = &encodedCrl;
1562 signInfo.cCrlEncoded = 1;
1563 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1565 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1567 check_param("signed with crl empty bare content", msg,
1568 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1569 sizeof(signedWithCrlEmptyBareContent));
1570 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1571 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1572 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1573 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1577 signInfo.cCertEncoded = 1;
1578 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1580 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1582 check_param("signed with cert and crl empty bare content", msg,
1583 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1584 sizeof(signedWithCertAndCrlEmptyBareContent));
1585 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1586 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1587 check_param("signed with cert and crl bare content", msg,
1588 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1589 sizeof(signedWithCertAndCrlBareContent));
1593 /* Test with a cert with a (bogus) public key */
1594 signInfo.cCrlEncoded = 0;
1595 encodedCert.cbData = sizeof(v1CertWithPubKey);
1596 encodedCert.pbData = v1CertWithPubKey;
1597 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1599 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1600 check_param("signedWithCertWithPubKeyBareContent", msg,
1601 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1602 sizeof(signedWithCertWithPubKeyBareContent));
1605 CryptDestroyKey(key);
1606 CryptReleaseContext(signer.hCryptProv, 0);
1607 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1608 CRYPT_DELETEKEYSET);
1611 static void test_signed_msg_get_param(void)
1615 DWORD size, value = 0;
1616 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1617 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1618 CERT_INFO certInfo = { 0 };
1620 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1622 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1624 /* Content and bare content are always gettable */
1626 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1627 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1629 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1630 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1631 /* For "signed" messages, so is the version. */
1633 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1634 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1635 size = sizeof(value);
1636 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1637 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1638 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1639 /* But for this message, with no signers, the hash and signer aren't
1643 SetLastError(0xdeadbeef);
1644 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1645 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1646 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1647 SetLastError(0xdeadbeef);
1648 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1649 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1650 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1651 /* As usual, the type isn't available. */
1652 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1653 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1654 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1658 certInfo.SerialNumber.cbData = sizeof(serialNum);
1659 certInfo.SerialNumber.pbData = serialNum;
1660 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1661 certInfo.Issuer.pbData = encodedCommonName;
1662 signer.pCertInfo = &certInfo;
1663 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1664 signInfo.cSigners = 1;
1665 signInfo.rgSigners = &signer;
1666 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1667 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1668 if (!ret && GetLastError() == NTE_EXISTS)
1669 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1671 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1672 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1674 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1676 /* This message, with one signer, has the hash and signer for index 0
1677 * available, but not for other indexes.
1680 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1681 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1682 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1683 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1685 SetLastError(0xdeadbeef);
1686 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1687 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1688 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1689 SetLastError(0xdeadbeef);
1690 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1691 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1692 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1693 /* As usual, the type isn't available. */
1694 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1695 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1696 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1700 CryptReleaseContext(signer.hCryptProv, 0);
1701 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1702 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1705 static void test_signed_msg(void)
1707 test_signed_msg_open();
1708 test_signed_msg_update();
1709 test_signed_msg_encoding();
1710 test_signed_msg_get_param();
1713 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1714 static const struct update_accum a4 = { 1, &b4 };
1716 static const BYTE bogusOIDContent[] = {
1717 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1719 static const BYTE bogusHashContent[] = {
1720 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1721 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1722 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1723 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1724 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1726 static void test_decode_msg_update(void)
1730 CMSG_STREAM_INFO streamInfo = { 0 };
1732 struct update_accum accum = { 0, NULL };
1734 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1735 /* Update with a full message in a final update */
1736 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1737 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1738 /* Can't update after a final update */
1739 SetLastError(0xdeadbeef);
1740 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1741 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1742 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1745 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1746 /* Can't send a non-final update without streaming */
1747 SetLastError(0xdeadbeef);
1748 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1750 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1751 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1752 /* A subsequent final update succeeds */
1753 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1754 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1757 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1758 /* Updating a message that has a NULL stream callback fails */
1759 SetLastError(0xdeadbeef);
1760 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1763 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1764 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1765 /* Changing the callback pointer after the fact yields the same error (so
1766 * the message must copy the stream info, not just store a pointer to it)
1768 streamInfo.pfnStreamOutput = nop_stream_output;
1769 SetLastError(0xdeadbeef);
1770 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1773 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1774 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1777 /* Empty non-final updates are allowed when streaming.. */
1778 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1779 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1780 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1781 /* but final updates aren't when not enough data has been received. */
1782 SetLastError(0xdeadbeef);
1783 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1785 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1786 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1789 /* Updating the message byte by byte is legal */
1790 streamInfo.pfnStreamOutput = accumulating_stream_output;
1791 streamInfo.pvArg = &accum;
1792 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1793 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1794 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1795 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1796 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1797 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1800 check_updates("byte-by-byte empty content", &a4, &accum);
1801 free_updates(&accum);
1803 /* Decoding bogus content fails in non-streaming mode.. */
1804 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1805 SetLastError(0xdeadbeef);
1806 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1807 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1808 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1810 /* and as the final update in streaming mode.. */
1811 streamInfo.pfnStreamOutput = nop_stream_output;
1812 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1813 SetLastError(0xdeadbeef);
1814 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1816 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1817 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1819 /* and even as a non-final update in streaming mode. */
1820 streamInfo.pfnStreamOutput = nop_stream_output;
1821 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1822 SetLastError(0xdeadbeef);
1823 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1825 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1826 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1829 /* An empty message can be opened with indetermined type.. */
1830 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1831 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1833 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1834 /* but decoding it as an explicitly typed message fails. */
1835 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1837 SetLastError(0xdeadbeef);
1838 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1840 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1841 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1843 /* On the other hand, decoding the bare content of an empty message fails
1844 * with unspecified type..
1846 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1847 SetLastError(0xdeadbeef);
1848 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1849 sizeof(dataEmptyBareContent), TRUE);
1850 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1851 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1853 /* but succeeds with explicit type. */
1854 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1856 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1857 sizeof(dataEmptyBareContent), TRUE);
1858 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1861 /* Decoding valid content with an unsupported OID fails */
1862 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1863 SetLastError(0xdeadbeef);
1864 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
1865 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1866 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1869 /* Similarly, opening an empty hash with unspecified type succeeds.. */
1870 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1871 SetLastError(0xdeadbeef);
1872 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1873 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1875 /* while with specified type it fails. */
1876 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1878 SetLastError(0xdeadbeef);
1879 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1880 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1881 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1883 /* On the other hand, decoding the bare content of an empty hash message
1884 * fails with unspecified type..
1886 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1887 SetLastError(0xdeadbeef);
1888 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1889 sizeof(hashEmptyBareContent), TRUE);
1890 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1891 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1893 /* but succeeds with explicit type. */
1894 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1896 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1897 sizeof(hashEmptyBareContent), TRUE);
1898 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1901 /* And again, opening a (non-empty) hash message with unspecified type
1904 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1905 SetLastError(0xdeadbeef);
1906 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
1907 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1909 /* while with specified type it fails.. */
1910 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1912 SetLastError(0xdeadbeef);
1913 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
1914 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1915 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1917 /* and decoding the bare content of a non-empty hash message fails with
1918 * unspecified type..
1920 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1921 SetLastError(0xdeadbeef);
1922 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
1923 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1924 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1926 /* but succeeds with explicit type. */
1927 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1929 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
1930 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1933 /* Opening a (non-empty) hash message with unspecified type and a bogus
1934 * hash value succeeds..
1936 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1937 SetLastError(0xdeadbeef);
1938 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
1939 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1942 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1943 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
1944 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1946 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1947 SetLastError(0xdeadbeef);
1948 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
1949 sizeof(signedWithCertAndCrlBareContent), TRUE);
1950 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1951 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1953 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
1955 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
1956 sizeof(signedWithCertAndCrlBareContent), TRUE);
1957 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1961 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
1962 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1964 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
1965 const CMSG_SIGNER_INFO *expected)
1967 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
1968 expected->dwVersion, got->dwVersion);
1969 ok(got->Issuer.cbData == expected->Issuer.cbData,
1970 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
1971 got->Issuer.cbData);
1972 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
1973 "Unexpected issuer\n");
1974 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
1975 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
1976 got->SerialNumber.cbData);
1977 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
1978 got->SerialNumber.cbData), "Unexpected serial number\n");
1979 /* FIXME: check more things */
1982 static void test_decode_msg_get_param(void)
1986 DWORD size = 0, value;
1989 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1990 SetLastError(0xdeadbeef);
1991 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1992 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1993 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1994 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
1995 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
1999 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2000 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2001 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2002 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2003 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2004 emptyHashParam, sizeof(emptyHashParam));
2006 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2007 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2008 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2010 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2012 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2013 hashParam, sizeof(hashParam));
2014 /* Curiously, getting the hash of index 1 succeeds, even though there's
2017 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2018 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2019 buf = CryptMemAlloc(size);
2022 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2023 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2024 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2027 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2028 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2029 value = CMSG_HASHED_DATA_V0;
2030 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2034 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2035 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2036 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2037 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2039 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2040 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2041 size = sizeof(value);
2043 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2044 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2045 ok(value == 1, "Expected 1 signer, got %d\n", value);
2047 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2048 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2050 buf = CryptMemAlloc(size);
2055 CMSG_SIGNER_INFO signer = { 0 };
2057 signer.dwVersion = 1;
2058 signer.Issuer.cbData = sizeof(encodedCommonName);
2059 signer.Issuer.pbData = encodedCommonName;
2060 signer.SerialNumber.cbData = sizeof(serialNum);
2061 signer.SerialNumber.pbData = serialNum;
2062 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2063 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2064 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2067 /* index is ignored when getting signer count */
2068 size = sizeof(value);
2069 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2070 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2071 ok(value == 1, "Expected 1 signer, got %d\n", value);
2072 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2073 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2074 ok(value == 0, "Expected 0 certs, got %d\n", value);
2075 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2076 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2077 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2079 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2081 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2082 sizeof(signedWithCertAndCrlBareContent), TRUE);
2083 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2084 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2085 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2086 ok(value == 1, "Expected 1 cert, got %d\n", value);
2087 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2088 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2089 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2090 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2091 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2095 static void test_decode_msg(void)
2097 test_decode_msg_update();
2098 test_decode_msg_get_param();
2103 init_function_pointers();
2105 /* Basic parameter checking tests */
2106 test_msg_open_to_encode();
2107 test_msg_open_to_decode();
2108 test_msg_get_param();
2111 /* Message-type specific tests */