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 /* For an encoded hash message, the hash data aren't available */
792 SetLastError(0xdeadbeef);
793 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
794 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
795 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
796 /* The hash is also available. */
798 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
799 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
800 ok(size == sizeof(buf), "Unexpected size %d\n", size);
801 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
802 if (size == sizeof(buf))
803 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
804 /* By getting the hash, further updates are not allowed */
805 SetLastError(0xdeadbeef);
806 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
807 ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
808 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
809 /* Even after a final update, the hash data aren't available */
810 SetLastError(0xdeadbeef);
811 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
812 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
813 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
814 /* The version is also available, and should be zero for this message. */
816 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
817 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
818 size = sizeof(value);
819 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
820 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
821 ok(value == 0, "Expected version 0, got %d\n", value);
822 /* As usual, the type isn't available. */
823 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
824 ok(!ret, "Expected failure\n");
827 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
829 /* Streamed messages don't allow you to get the content or bare content. */
830 SetLastError(0xdeadbeef);
831 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
832 ok(!ret && GetLastError() == E_INVALIDARG,
833 "Expected E_INVALIDARG, got %x\n", GetLastError());
834 SetLastError(0xdeadbeef);
835 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
836 ok(!ret && GetLastError() == E_INVALIDARG,
837 "Expected E_INVALIDARG, got %x\n", GetLastError());
838 /* The hash is still available. */
840 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
841 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
842 ok(size == sizeof(buf), "Unexpected size %d\n", size);
843 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
844 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
845 if (size == sizeof(buf))
846 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
847 /* After updating the hash, further updates aren't allowed on streamed
850 SetLastError(0xdeadbeef);
851 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
852 ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
853 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
857 static const BYTE hashEmptyBareContent[] = {
858 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
859 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
860 static const BYTE hashEmptyContent[] = {
861 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
862 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
863 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
864 static const BYTE hashBareContent[] = {
865 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
866 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
867 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
868 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
869 static const BYTE hashContent[] = {
870 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
871 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
872 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
873 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
874 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
876 static const BYTE detachedHashNonFinalBareContent[] = {
877 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
878 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
879 0x07,0x01,0x04,0x00 };
880 static const BYTE detachedHashNonFinalContent[] = {
881 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
882 0x30,0x20,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,0x00 };
885 static const BYTE detachedHashBareContent[] = {
886 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
887 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
888 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
889 0x9d,0x2a,0x8f,0x26,0x2f };
890 static const BYTE detachedHashContent[] = {
891 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
892 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
893 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
894 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
895 0x9d,0x2a,0x8f,0x26,0x2f };
897 static void test_hash_msg_encoding(void)
900 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
902 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
903 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
905 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
906 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
908 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
909 hashEmptyBareContent, sizeof(hashEmptyBareContent));
910 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
911 hashEmptyContent, sizeof(hashEmptyContent));
912 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
913 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
914 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
915 hashBareContent, sizeof(hashBareContent));
916 check_param("hash content", msg, CMSG_CONTENT_PARAM,
917 hashContent, sizeof(hashContent));
919 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
920 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
921 CMSG_HASHED, &hashInfo, NULL, NULL);
922 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
923 hashEmptyBareContent, sizeof(hashEmptyBareContent));
924 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
925 hashEmptyContent, sizeof(hashEmptyContent));
926 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
927 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
928 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
929 hashBareContent, sizeof(hashBareContent));
930 check_param("hash content", msg, CMSG_CONTENT_PARAM,
931 hashContent, sizeof(hashContent));
933 /* Same test, but with CMSG_DETACHED_FLAG set */
934 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
935 CMSG_HASHED, &hashInfo, NULL, NULL);
936 check_param("detached hash empty bare content", msg,
937 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
938 sizeof(hashEmptyBareContent));
939 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
940 hashEmptyContent, sizeof(hashEmptyContent));
941 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
942 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
943 check_param("detached hash not final bare content", msg,
944 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
945 sizeof(detachedHashNonFinalBareContent));
946 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
947 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
948 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
949 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
950 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
951 detachedHashBareContent, sizeof(detachedHashBareContent));
952 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
953 detachedHashContent, sizeof(detachedHashContent));
954 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
955 detachedHashBareContent, sizeof(detachedHashBareContent));
956 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
957 detachedHashContent, sizeof(detachedHashContent));
959 /* In what appears to be a bug, streamed updates to hash messages don't
960 * call the output function.
962 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
964 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
965 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
966 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
967 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
969 check_updates("empty hash message", &empty_accum, &accum);
970 free_updates(&accum);
972 streamInfo.cbContent = sizeof(msgData);
973 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
975 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
976 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
978 check_updates("hash message", &empty_accum, &accum);
979 free_updates(&accum);
981 streamInfo.cbContent = sizeof(msgData);
982 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
983 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
984 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
985 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
987 check_updates("detached hash message", &empty_accum, &accum);
988 free_updates(&accum);
991 static void test_hash_msg(void)
993 test_hash_msg_open();
994 test_hash_msg_update();
995 test_hash_msg_get_param();
996 test_hash_msg_encoding();
999 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1001 static BYTE serialNum[] = { 1 };
1002 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1003 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1005 static void test_signed_msg_open(void)
1009 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1010 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1011 CERT_INFO certInfo = { 0 };
1013 SetLastError(0xdeadbeef);
1014 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1016 ok(!msg && GetLastError() == E_INVALIDARG,
1017 "Expected E_INVALIDARG, got %x\n", GetLastError());
1018 signInfo.cbSize = sizeof(signInfo);
1019 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1021 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1024 signInfo.cSigners = 1;
1025 signInfo.rgSigners = &signer;
1026 /* With signer.pCertInfo unset, attempting to open this message this
1029 signer.pCertInfo = &certInfo;
1030 /* The cert info must contain a serial number and an issuer. */
1031 SetLastError(0xdeadbeef);
1032 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1034 ok(!msg && GetLastError() == E_INVALIDARG,
1035 "Expected E_INVALIDARG, got %x\n", GetLastError());
1036 certInfo.SerialNumber.cbData = sizeof(serialNum);
1037 certInfo.SerialNumber.pbData = serialNum;
1038 SetLastError(0xdeadbeef);
1039 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1041 ok(!msg && GetLastError() == E_INVALIDARG,
1042 "Expected E_INVALIDARG, got %x\n", GetLastError());
1043 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1044 certInfo.Issuer.pbData = encodedCommonName;
1045 SetLastError(0xdeadbeef);
1046 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1048 ok(!msg && GetLastError() == E_INVALIDARG,
1049 "Expected E_INVALIDARG, got %x\n", GetLastError());
1051 /* The signer's hCryptProv must be set to something. Whether it's usable
1052 * or not will be checked after the hash algorithm is checked (see next
1055 signer.hCryptProv = 1;
1056 SetLastError(0xdeadbeef);
1057 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1059 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1060 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1061 /* The signer's hash algorithm must also be set. */
1062 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1063 SetLastError(0xdeadbeef);
1064 /* Crashes in advapi32 in wine, don't do it */
1066 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1067 &signInfo, NULL, NULL);
1068 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1069 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1071 /* The signer's hCryptProv must also be valid. */
1072 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1073 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1074 if (!ret && GetLastError() == NTE_EXISTS)
1075 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1077 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1078 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1080 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1083 CryptReleaseContext(signer.hCryptProv, 0);
1084 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1085 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1088 static const BYTE privKey[] = {
1089 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1090 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1091 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1092 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1093 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1094 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1095 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1096 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1097 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1098 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1099 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1100 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1101 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1102 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1103 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1104 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1105 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1106 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1107 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1108 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1109 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1110 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1111 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1112 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1114 static void test_signed_msg_update(void)
1118 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1119 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1120 CERT_INFO certInfo = { 0 };
1123 certInfo.SerialNumber.cbData = sizeof(serialNum);
1124 certInfo.SerialNumber.pbData = serialNum;
1125 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1126 certInfo.Issuer.pbData = encodedCommonName;
1127 signer.pCertInfo = &certInfo;
1128 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1129 signInfo.cSigners = 1;
1130 signInfo.rgSigners = &signer;
1131 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1132 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1133 if (!ret && GetLastError() == NTE_EXISTS)
1134 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1136 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1137 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1138 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1139 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1140 /* Detached CMSG_SIGNED allows non-final updates. */
1141 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1142 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1143 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1144 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1145 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1146 /* The final update requires a private key in the hCryptProv, in order to
1147 * generate the signature.
1149 SetLastError(0xdeadbeef);
1150 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1151 ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1152 GetLastError() == NTE_NO_KEY),
1153 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1154 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1156 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1157 /* The final update should be able to succeed now that a key exists, but
1158 * the previous (invalid) final update prevents it.
1160 SetLastError(0xdeadbeef);
1161 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1162 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1163 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1166 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1167 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1168 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1169 /* Detached CMSG_SIGNED allows non-final updates. */
1170 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1171 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1172 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1173 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1174 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1175 /* Now that the private key exists, the final update can succeed (even
1178 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1179 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1180 /* But no updates are allowed after the final update. */
1181 SetLastError(0xdeadbeef);
1182 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1183 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1184 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1185 SetLastError(0xdeadbeef);
1186 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1187 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1188 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1191 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1193 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1194 /* Non-detached messages don't allow non-final updates.. */
1195 SetLastError(0xdeadbeef);
1196 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1197 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1198 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1199 /* but they do allow final ones. */
1200 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1201 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1203 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1205 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1206 /* They also allow final updates with no data. */
1207 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1208 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1211 CryptDestroyKey(key);
1212 CryptReleaseContext(signer.hCryptProv, 0);
1213 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1214 CRYPT_DELETEKEYSET);
1217 static const BYTE signedEmptyBareContent[] = {
1218 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1219 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1220 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1221 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1222 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1223 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1224 static const BYTE signedEmptyContent[] = {
1225 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1226 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1227 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1228 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1229 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1230 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1231 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1232 static const BYTE detachedSignedBareContent[] = {
1233 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1234 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1235 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1236 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1237 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1238 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1239 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1240 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1241 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1242 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1243 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1244 static const BYTE detachedSignedContent[] = {
1245 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1246 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1247 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1248 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1249 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1250 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1251 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1252 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1253 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1254 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1255 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1256 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1257 static const BYTE signedBareContent[] = {
1258 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1259 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1260 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1261 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1262 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1263 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1264 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1265 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1266 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1267 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1268 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1269 static const BYTE signedContent[] = {
1270 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1271 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1272 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1273 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1274 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1275 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1276 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1277 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1278 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1279 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1280 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1281 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1283 static const BYTE signedHash[] = {
1284 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1286 static const BYTE signedEncodedSigner[] = {
1287 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1288 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1289 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1290 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1291 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1292 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1293 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1294 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1295 static const BYTE signedWithAuthAttrsBareContent[] = {
1296 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1297 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1298 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1299 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1300 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1301 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1302 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1303 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1304 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1305 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1306 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1307 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1308 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1309 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1310 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1311 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1312 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1313 0xff,0xc6,0x33,0x63,0x34 };
1314 static BYTE cert[] = {
1315 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1316 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1317 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1318 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1319 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1320 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1321 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1322 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1323 0xff,0x02,0x01,0x01 };
1324 static BYTE v1CertWithPubKey[] = {
1325 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1326 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1327 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1328 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1329 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1330 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1331 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1332 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1333 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1334 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1336 static const BYTE signedWithCertEmptyBareContent[] = {
1337 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1338 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1339 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1340 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1341 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1342 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1343 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1344 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1345 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1346 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1347 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1348 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1349 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1350 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1351 static const BYTE signedWithCertBareContent[] = {
1352 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1353 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1354 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1355 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1356 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1357 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1358 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1359 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1360 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1361 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1362 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1363 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1364 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1365 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1366 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1367 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1368 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1369 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1370 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1371 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1372 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1373 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1374 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1375 0x30,0x30,0x30,0x30,0x5a };
1376 static const BYTE signedWithCrlEmptyBareContent[] = {
1377 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1378 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1379 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1380 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1381 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1382 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1383 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1384 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1385 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1386 static const BYTE signedWithCrlBareContent[] = {
1387 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1388 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1389 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1390 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1391 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1392 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1393 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1394 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1395 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1396 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1397 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1398 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1399 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1400 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1402 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1403 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1404 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1405 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1406 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1407 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1408 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1409 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1410 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1411 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1412 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1413 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1414 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1415 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1416 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1417 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1418 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1419 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1421 static const BYTE signedWithCertAndCrlBareContent[] = {
1422 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1423 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1424 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1425 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1426 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1427 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1428 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1429 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1430 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1431 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1432 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1433 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1434 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1435 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1436 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1437 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1438 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1439 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1440 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1441 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1442 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1443 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1444 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1445 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1446 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1447 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1448 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1449 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1450 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1451 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1452 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1453 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1454 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1455 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1456 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1457 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1458 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1459 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1460 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1461 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1463 static void test_signed_msg_encoding(void)
1466 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1467 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1468 CERT_INFO certInfo = { 0 };
1469 CERT_BLOB encodedCert = { sizeof(cert), cert };
1470 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1471 char oid_common_name[] = szOID_COMMON_NAME;
1472 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1473 encodedCommonName };
1474 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1479 certInfo.SerialNumber.cbData = sizeof(serialNum);
1480 certInfo.SerialNumber.pbData = serialNum;
1481 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1482 certInfo.Issuer.pbData = encodedCommonName;
1483 signer.pCertInfo = &certInfo;
1484 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1485 signInfo.cSigners = 1;
1486 signInfo.rgSigners = &signer;
1487 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1488 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1489 if (!ret && GetLastError() == NTE_EXISTS)
1490 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1492 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1493 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1495 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1497 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1498 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1499 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1501 check_param("detached signed empty bare content", msg,
1502 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1503 sizeof(signedEmptyBareContent));
1504 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1505 signedEmptyContent, sizeof(signedEmptyContent));
1506 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1507 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1508 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1509 signedHash, sizeof(signedHash));
1510 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1511 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1512 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1513 detachedSignedContent, sizeof(detachedSignedContent));
1514 SetLastError(0xdeadbeef);
1515 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1516 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1517 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1518 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1519 signedEncodedSigner, sizeof(signedEncodedSigner));
1523 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1525 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1527 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1528 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1529 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1530 signedEmptyContent, sizeof(signedEmptyContent));
1531 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1532 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1533 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1534 signedBareContent, sizeof(signedBareContent));
1535 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1536 signedContent, sizeof(signedContent));
1540 signer.cAuthAttr = 1;
1541 signer.rgAuthAttr = &attr;
1542 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1544 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1546 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1547 check_param("signed with auth attrs bare content", msg,
1548 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1549 sizeof(signedWithAuthAttrsBareContent));
1553 signer.cAuthAttr = 0;
1554 signInfo.rgCertEncoded = &encodedCert;
1555 signInfo.cCertEncoded = 1;
1556 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1558 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1560 check_param("signed with cert empty bare content", msg,
1561 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1562 sizeof(signedWithCertEmptyBareContent));
1563 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1564 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1565 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1566 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1570 signInfo.cCertEncoded = 0;
1571 signInfo.rgCrlEncoded = &encodedCrl;
1572 signInfo.cCrlEncoded = 1;
1573 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1575 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1577 check_param("signed with crl empty bare content", msg,
1578 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1579 sizeof(signedWithCrlEmptyBareContent));
1580 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1581 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1582 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1583 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1587 signInfo.cCertEncoded = 1;
1588 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1590 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1592 check_param("signed with cert and crl empty bare content", msg,
1593 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1594 sizeof(signedWithCertAndCrlEmptyBareContent));
1595 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1596 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1597 check_param("signed with cert and crl bare content", msg,
1598 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1599 sizeof(signedWithCertAndCrlBareContent));
1603 /* Test with a cert with a (bogus) public key */
1604 signInfo.cCrlEncoded = 0;
1605 encodedCert.cbData = sizeof(v1CertWithPubKey);
1606 encodedCert.pbData = v1CertWithPubKey;
1607 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1609 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1610 check_param("signedWithCertWithPubKeyBareContent", msg,
1611 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1612 sizeof(signedWithCertWithPubKeyBareContent));
1615 CryptDestroyKey(key);
1616 CryptReleaseContext(signer.hCryptProv, 0);
1617 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1618 CRYPT_DELETEKEYSET);
1621 static void test_signed_msg_get_param(void)
1625 DWORD size, value = 0;
1626 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1627 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1628 CERT_INFO certInfo = { 0 };
1630 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1632 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1634 /* Content and bare content are always gettable */
1636 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1637 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1639 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1640 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1641 /* For "signed" messages, so is the version. */
1643 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1644 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1645 size = sizeof(value);
1646 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1647 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1648 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1649 /* But for this message, with no signers, the hash and signer aren't
1653 SetLastError(0xdeadbeef);
1654 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1655 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1656 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1657 SetLastError(0xdeadbeef);
1658 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1659 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1660 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1661 /* As usual, the type isn't available. */
1662 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1663 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1664 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1668 certInfo.SerialNumber.cbData = sizeof(serialNum);
1669 certInfo.SerialNumber.pbData = serialNum;
1670 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1671 certInfo.Issuer.pbData = encodedCommonName;
1672 signer.pCertInfo = &certInfo;
1673 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1674 signInfo.cSigners = 1;
1675 signInfo.rgSigners = &signer;
1676 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1677 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1678 if (!ret && GetLastError() == NTE_EXISTS)
1679 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1681 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1682 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1684 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1686 /* This message, with one signer, has the hash and signer for index 0
1687 * available, but not for other indexes.
1690 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1691 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1692 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1693 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1695 SetLastError(0xdeadbeef);
1696 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1697 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1698 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1699 SetLastError(0xdeadbeef);
1700 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1701 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1702 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1703 /* As usual, the type isn't available. */
1704 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1705 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1706 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1710 CryptReleaseContext(signer.hCryptProv, 0);
1711 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1712 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1715 static void test_signed_msg(void)
1717 test_signed_msg_open();
1718 test_signed_msg_update();
1719 test_signed_msg_encoding();
1720 test_signed_msg_get_param();
1723 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1724 static const struct update_accum a4 = { 1, &b4 };
1726 static const BYTE bogusOIDContent[] = {
1727 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1729 static const BYTE bogusHashContent[] = {
1730 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1731 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1732 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1733 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1734 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1736 static void test_decode_msg_update(void)
1740 CMSG_STREAM_INFO streamInfo = { 0 };
1742 struct update_accum accum = { 0, NULL };
1744 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1745 /* Update with a full message in a final update */
1746 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1747 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1748 /* Can't update after a final update */
1749 SetLastError(0xdeadbeef);
1750 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1751 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1752 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1755 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1756 /* Can't send a non-final update without streaming */
1757 SetLastError(0xdeadbeef);
1758 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1760 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1761 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1762 /* A subsequent final update succeeds */
1763 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1764 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1767 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1768 /* Updating a message that has a NULL stream callback fails */
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());
1775 /* Changing the callback pointer after the fact yields the same error (so
1776 * the message must copy the stream info, not just store a pointer to it)
1778 streamInfo.pfnStreamOutput = nop_stream_output;
1779 SetLastError(0xdeadbeef);
1780 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1783 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1784 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1787 /* Empty non-final updates are allowed when streaming.. */
1788 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1789 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1790 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1791 /* but final updates aren't when not enough data has been received. */
1792 SetLastError(0xdeadbeef);
1793 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1795 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1796 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1799 /* Updating the message byte by byte is legal */
1800 streamInfo.pfnStreamOutput = accumulating_stream_output;
1801 streamInfo.pvArg = &accum;
1802 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1803 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1804 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1805 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1806 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1807 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1810 check_updates("byte-by-byte empty content", &a4, &accum);
1811 free_updates(&accum);
1813 /* Decoding bogus content fails in non-streaming mode.. */
1814 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1815 SetLastError(0xdeadbeef);
1816 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1817 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1818 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1820 /* and as the final update in streaming mode.. */
1821 streamInfo.pfnStreamOutput = nop_stream_output;
1822 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1823 SetLastError(0xdeadbeef);
1824 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1826 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1827 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1829 /* and even as a non-final update in streaming mode. */
1830 streamInfo.pfnStreamOutput = nop_stream_output;
1831 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1832 SetLastError(0xdeadbeef);
1833 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1835 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1836 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1839 /* An empty message can be opened with indetermined type.. */
1840 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1841 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1843 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1844 /* but decoding it as an explicitly typed message fails. */
1845 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1847 SetLastError(0xdeadbeef);
1848 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1850 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1851 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1853 /* On the other hand, decoding the bare content of an empty message fails
1854 * with unspecified type..
1856 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1857 SetLastError(0xdeadbeef);
1858 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1859 sizeof(dataEmptyBareContent), TRUE);
1860 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1861 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1863 /* but succeeds with explicit type. */
1864 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1866 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1867 sizeof(dataEmptyBareContent), TRUE);
1868 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1871 /* Decoding valid content with an unsupported OID fails */
1872 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1873 SetLastError(0xdeadbeef);
1874 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
1875 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1876 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1879 /* Similarly, opening an empty hash with unspecified type succeeds.. */
1880 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1881 SetLastError(0xdeadbeef);
1882 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1883 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1885 /* while with specified type it fails. */
1886 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1888 SetLastError(0xdeadbeef);
1889 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1890 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1891 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1893 /* On the other hand, decoding the bare content of an empty hash message
1894 * fails with unspecified type..
1896 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1897 SetLastError(0xdeadbeef);
1898 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1899 sizeof(hashEmptyBareContent), TRUE);
1900 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1901 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1903 /* but succeeds with explicit type. */
1904 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1906 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1907 sizeof(hashEmptyBareContent), TRUE);
1908 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1911 /* And again, opening a (non-empty) hash message with unspecified type
1914 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1915 SetLastError(0xdeadbeef);
1916 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
1917 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1919 /* while with specified type it fails.. */
1920 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1922 SetLastError(0xdeadbeef);
1923 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
1924 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1925 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1927 /* and decoding the bare content of a non-empty hash message fails with
1928 * unspecified type..
1930 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1931 SetLastError(0xdeadbeef);
1932 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
1933 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1934 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1936 /* but succeeds with explicit type. */
1937 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1939 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
1940 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1943 /* Opening a (non-empty) hash message with unspecified type and a bogus
1944 * hash value succeeds..
1946 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1947 SetLastError(0xdeadbeef);
1948 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
1949 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1952 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1953 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
1954 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1956 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1957 SetLastError(0xdeadbeef);
1958 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
1959 sizeof(signedWithCertAndCrlBareContent), TRUE);
1960 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1961 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1963 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
1965 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
1966 sizeof(signedWithCertAndCrlBareContent), TRUE);
1967 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1971 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
1972 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1974 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
1975 const CMSG_SIGNER_INFO *expected)
1977 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
1978 expected->dwVersion, got->dwVersion);
1979 ok(got->Issuer.cbData == expected->Issuer.cbData,
1980 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
1981 got->Issuer.cbData);
1982 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
1983 "Unexpected issuer\n");
1984 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
1985 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
1986 got->SerialNumber.cbData);
1987 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
1988 got->SerialNumber.cbData), "Unexpected serial number\n");
1989 /* FIXME: check more things */
1992 static void test_decode_msg_get_param(void)
1996 DWORD size = 0, value;
1999 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2000 SetLastError(0xdeadbeef);
2001 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2002 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2003 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2004 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2005 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2009 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2010 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2011 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2012 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2013 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2014 emptyHashParam, sizeof(emptyHashParam));
2016 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2017 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2018 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2020 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2022 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2023 hashParam, sizeof(hashParam));
2024 /* Curiously, getting the hash of index 1 succeeds, even though there's
2027 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2028 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2029 buf = CryptMemAlloc(size);
2032 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2033 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2034 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2037 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2038 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2039 value = CMSG_HASHED_DATA_V0;
2040 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2044 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2045 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2046 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2047 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2049 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2050 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2051 size = sizeof(value);
2053 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2054 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2055 ok(value == 1, "Expected 1 signer, got %d\n", value);
2057 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2058 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2060 buf = CryptMemAlloc(size);
2065 CMSG_SIGNER_INFO signer = { 0 };
2067 signer.dwVersion = 1;
2068 signer.Issuer.cbData = sizeof(encodedCommonName);
2069 signer.Issuer.pbData = encodedCommonName;
2070 signer.SerialNumber.cbData = sizeof(serialNum);
2071 signer.SerialNumber.pbData = serialNum;
2072 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2073 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2074 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2077 /* index is ignored when getting signer count */
2078 size = sizeof(value);
2079 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2080 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2081 ok(value == 1, "Expected 1 signer, got %d\n", value);
2082 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2083 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2084 ok(value == 0, "Expected 0 certs, got %d\n", value);
2085 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2086 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2087 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2089 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2091 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2092 sizeof(signedWithCertAndCrlBareContent), TRUE);
2093 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2094 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2095 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2096 ok(value == 1, "Expected 1 cert, got %d\n", value);
2097 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2098 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2099 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2100 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2101 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2105 static void test_decode_msg(void)
2107 test_decode_msg_update();
2108 test_decode_msg_get_param();
2111 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2112 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2113 static BYTE encodedPubKey[] = {
2114 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2115 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2117 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2118 static BYTE mod_encoded[] = {
2119 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2122 static void test_msg_control(void)
2124 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2128 CERT_INFO certInfo = { 0 };
2129 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2130 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2131 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2134 ret = CryptMsgControl(NULL, 0, 0, NULL);
2137 /* Data encode messages don't allow any sort of control.. */
2138 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2140 /* either with no prior update.. */
2141 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2143 SetLastError(0xdeadbeef);
2144 ret = CryptMsgControl(msg, 0, i, NULL);
2145 ok(!ret && GetLastError() == E_INVALIDARG,
2146 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2148 /* or after an update. */
2149 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2151 SetLastError(0xdeadbeef);
2152 ret = CryptMsgControl(msg, 0, i, NULL);
2153 ok(!ret && GetLastError() == E_INVALIDARG,
2154 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2158 /* Hash encode messages don't allow any sort of control.. */
2159 hashInfo.cbSize = sizeof(hashInfo);
2160 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2161 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2163 /* either with no prior update.. */
2164 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2166 SetLastError(0xdeadbeef);
2167 ret = CryptMsgControl(msg, 0, i, NULL);
2168 ok(!ret && GetLastError() == E_INVALIDARG,
2169 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2171 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2172 /* or after an update. */
2173 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2175 SetLastError(0xdeadbeef);
2176 ret = CryptMsgControl(msg, 0, i, NULL);
2177 ok(!ret && GetLastError() == E_INVALIDARG,
2178 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2182 /* Signed encode messages likewise don't allow any sort of control.. */
2183 signInfo.cbSize = sizeof(signInfo);
2184 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2186 /* either before an update.. */
2187 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2189 SetLastError(0xdeadbeef);
2190 ret = CryptMsgControl(msg, 0, i, NULL);
2191 ok(!ret && GetLastError() == E_INVALIDARG,
2192 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2194 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2195 /* or after an update. */
2196 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2198 SetLastError(0xdeadbeef);
2199 ret = CryptMsgControl(msg, 0, i, NULL);
2200 ok(!ret && GetLastError() == E_INVALIDARG,
2201 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2205 /* Decode messages behave a bit differently. */
2206 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2207 /* Bad control type */
2208 SetLastError(0xdeadbeef);
2209 ret = CryptMsgControl(msg, 0, 0, NULL);
2210 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2211 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2212 SetLastError(0xdeadbeef);
2213 ret = CryptMsgControl(msg, 1, 0, NULL);
2214 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2215 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2216 /* Can't verify the hash of an indeterminate-type message */
2217 SetLastError(0xdeadbeef);
2218 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2219 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2220 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2222 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2224 /* Can't decrypt an indeterminate-type message */
2225 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2226 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2227 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2230 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2232 /* Can't verify the hash of an empty message */
2233 SetLastError(0xdeadbeef);
2234 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2236 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2237 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2239 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2241 /* Can't verify the signature of a hash message */
2242 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2243 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2244 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2245 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2247 /* Oddly enough, this fails */
2248 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2250 ok(!ret, "Expected failure\n");
2252 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2254 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2255 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2256 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2257 /* Can't decrypt an indeterminate-type message */
2258 SetLastError(0xdeadbeef);
2259 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2260 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2261 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2264 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2266 /* Can't verify the hash of a signed message */
2267 SetLastError(0xdeadbeef);
2268 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2269 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2270 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2271 /* Can't decrypt a signed message */
2272 SetLastError(0xdeadbeef);
2273 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2274 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2275 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2277 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2278 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2280 CryptMsgUpdate(msg, signedWithCertBareContent,
2281 sizeof(signedWithCertBareContent), TRUE);
2282 /* With an empty cert info, the signer can't be found in the message (and
2283 * the signature can't be verified.
2285 SetLastError(0xdeadbeef);
2286 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2288 ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2289 "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2290 /* The cert info is expected to have an issuer, serial number, and public
2293 certInfo.SerialNumber.cbData = sizeof(serialNum);
2294 certInfo.SerialNumber.pbData = serialNum;
2295 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2296 certInfo.Issuer.pbData = encodedCommonName;
2297 SetLastError(0xdeadbeef);
2298 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2300 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2301 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2303 /* This cert has a public key, but it's not in a usable form */
2304 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2306 CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2307 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2308 /* Again, cert info needs to have a public key set */
2309 SetLastError(0xdeadbeef);
2310 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2312 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2313 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2314 /* The public key is supposed to be in encoded form.. */
2315 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2316 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2317 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2318 SetLastError(0xdeadbeef);
2319 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2321 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2322 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2323 /* but not as a X509_PUBLIC_KEY_INFO.. */
2324 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2325 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2326 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2327 SetLastError(0xdeadbeef);
2328 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2330 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2331 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2332 /* This decodes successfully, but it doesn't match any key in the message */
2333 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2334 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2335 SetLastError(0xdeadbeef);
2336 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2338 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2339 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2341 /* FIXME: need to test with a message with a valid signature and signer */
2346 init_function_pointers();
2348 /* Basic parameter checking tests */
2349 test_msg_open_to_encode();
2350 test_msg_open_to_decode();
2351 test_msg_get_param();
2355 /* Message-type specific tests */