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);
662 check_updates("data message with indefinite length", &a3, &accum);
663 free_updates(&accum);
666 static void test_data_msg(void)
668 test_data_msg_open();
669 test_data_msg_update();
670 test_data_msg_get_param();
671 test_data_msg_encoding();
674 static void test_hash_msg_open(void)
677 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
678 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
680 SetLastError(0xdeadbeef);
681 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
683 ok(!msg && GetLastError() == E_INVALIDARG,
684 "Expected E_INVALIDARG, got %x\n", GetLastError());
685 hashInfo.cbSize = sizeof(hashInfo);
686 SetLastError(0xdeadbeef);
687 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
689 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
690 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
691 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
692 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
694 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
696 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
697 CMSG_HASHED, &hashInfo, NULL, NULL);
698 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
700 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
701 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
702 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
706 static void test_hash_msg_update(void)
710 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
711 { oid_rsa_md5, { 0, NULL } }, NULL };
712 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
714 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
715 CMSG_HASHED, &hashInfo, NULL, NULL);
716 /* Detached hashed messages opened in non-streaming mode allow non-final
719 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
720 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
721 /* including non-final updates with no data.. */
722 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
723 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
724 /* and final updates with no data. */
725 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
726 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
727 /* But no updates are allowed after the final update. */
728 SetLastError(0xdeadbeef);
729 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
730 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
731 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
732 SetLastError(0xdeadbeef);
733 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
734 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
735 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
737 /* Non-detached messages, in contrast, don't allow non-final updates in
738 * non-streaming mode.
740 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
742 SetLastError(0xdeadbeef);
743 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
744 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
745 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
746 /* Final updates (including empty ones) are allowed. */
747 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
748 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
750 /* And, of course, streaming mode allows non-final updates */
751 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
753 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
754 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
756 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
757 * to be a bug, it isn't actually used - see encoding tests.)
759 streamInfo.pfnStreamOutput = NULL;
760 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
762 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
763 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
767 static const BYTE emptyHashParam[] = {
768 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
771 static void test_hash_msg_get_param(void)
775 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
776 { oid_rsa_md5, { 0, NULL } }, NULL };
778 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
781 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
783 /* Content and bare content are always gettable for non-streamed messages */
785 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
786 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
788 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
789 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
790 /* For an encoded hash message, the hash data aren't available */
791 SetLastError(0xdeadbeef);
792 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
793 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
794 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
795 /* The hash is also available. */
797 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
798 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
799 ok(size == sizeof(buf), "Unexpected size %d\n", size);
800 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
801 if (size == sizeof(buf))
802 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
803 /* By getting the hash, further updates are not allowed */
804 SetLastError(0xdeadbeef);
805 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
806 ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
807 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
808 /* Even after a final update, the hash data aren't available */
809 SetLastError(0xdeadbeef);
810 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
811 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
812 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
813 /* The version is also available, and should be zero for this message. */
815 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
816 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
817 size = sizeof(value);
818 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
819 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
820 ok(value == 0, "Expected version 0, got %d\n", value);
821 /* As usual, the type isn't available. */
822 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
823 ok(!ret, "Expected failure\n");
826 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
828 /* Streamed messages don't allow you to get the content or bare content. */
829 SetLastError(0xdeadbeef);
830 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
831 ok(!ret && GetLastError() == E_INVALIDARG,
832 "Expected E_INVALIDARG, got %x\n", GetLastError());
833 SetLastError(0xdeadbeef);
834 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
835 ok(!ret && GetLastError() == E_INVALIDARG,
836 "Expected E_INVALIDARG, got %x\n", GetLastError());
837 /* The hash is still available. */
839 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
840 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
841 ok(size == sizeof(buf), "Unexpected size %d\n", size);
842 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
843 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
844 if (size == sizeof(buf))
845 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
846 /* After updating the hash, further updates aren't allowed on streamed
849 SetLastError(0xdeadbeef);
850 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
851 ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
852 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
856 static const BYTE hashEmptyBareContent[] = {
857 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
858 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
859 static const BYTE hashEmptyContent[] = {
860 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
861 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
862 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
863 static const BYTE hashBareContent[] = {
864 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
865 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
866 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
867 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
868 static const BYTE hashContent[] = {
869 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
870 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
871 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
872 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
873 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
875 static const BYTE detachedHashNonFinalBareContent[] = {
876 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
877 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
878 0x07,0x01,0x04,0x00 };
879 static const BYTE detachedHashNonFinalContent[] = {
880 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
881 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
882 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
883 0x07,0x01,0x04,0x00 };
884 static const BYTE detachedHashBareContent[] = {
885 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
886 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
887 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
888 0x9d,0x2a,0x8f,0x26,0x2f };
889 static const BYTE detachedHashContent[] = {
890 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
891 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
892 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
893 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
894 0x9d,0x2a,0x8f,0x26,0x2f };
896 static void test_hash_msg_encoding(void)
899 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
901 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
902 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
904 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
905 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
907 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
908 hashEmptyBareContent, sizeof(hashEmptyBareContent));
909 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
910 hashEmptyContent, sizeof(hashEmptyContent));
911 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
912 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
913 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
914 hashBareContent, sizeof(hashBareContent));
915 check_param("hash content", msg, CMSG_CONTENT_PARAM,
916 hashContent, sizeof(hashContent));
918 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
919 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
920 CMSG_HASHED, &hashInfo, NULL, NULL);
921 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
922 hashEmptyBareContent, sizeof(hashEmptyBareContent));
923 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
924 hashEmptyContent, sizeof(hashEmptyContent));
925 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
926 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
927 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
928 hashBareContent, sizeof(hashBareContent));
929 check_param("hash content", msg, CMSG_CONTENT_PARAM,
930 hashContent, sizeof(hashContent));
932 /* Same test, but with CMSG_DETACHED_FLAG set */
933 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
934 CMSG_HASHED, &hashInfo, NULL, NULL);
935 check_param("detached hash empty bare content", msg,
936 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
937 sizeof(hashEmptyBareContent));
938 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
939 hashEmptyContent, sizeof(hashEmptyContent));
940 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
941 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
942 check_param("detached hash not final bare content", msg,
943 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
944 sizeof(detachedHashNonFinalBareContent));
945 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
946 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
947 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
948 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
949 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
950 detachedHashBareContent, sizeof(detachedHashBareContent));
951 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
952 detachedHashContent, sizeof(detachedHashContent));
953 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
954 detachedHashBareContent, sizeof(detachedHashBareContent));
955 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
956 detachedHashContent, sizeof(detachedHashContent));
958 /* In what appears to be a bug, streamed updates to hash messages don't
959 * call the output function.
961 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
963 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
964 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
965 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
966 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
968 check_updates("empty hash message", &empty_accum, &accum);
969 free_updates(&accum);
971 streamInfo.cbContent = sizeof(msgData);
972 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
974 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
975 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
977 check_updates("hash message", &empty_accum, &accum);
978 free_updates(&accum);
980 streamInfo.cbContent = sizeof(msgData);
981 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
982 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
983 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
984 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
986 check_updates("detached hash message", &empty_accum, &accum);
987 free_updates(&accum);
990 static void test_hash_msg(void)
992 test_hash_msg_open();
993 test_hash_msg_update();
994 test_hash_msg_get_param();
995 test_hash_msg_encoding();
998 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1000 static BYTE serialNum[] = { 1 };
1001 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1002 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1004 static void test_signed_msg_open(void)
1008 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1009 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1010 CERT_INFO certInfo = { 0 };
1012 SetLastError(0xdeadbeef);
1013 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1015 ok(!msg && GetLastError() == E_INVALIDARG,
1016 "Expected E_INVALIDARG, got %x\n", GetLastError());
1017 signInfo.cbSize = sizeof(signInfo);
1018 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1020 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1023 signInfo.cSigners = 1;
1024 signInfo.rgSigners = &signer;
1025 /* With signer.pCertInfo unset, attempting to open this message this
1028 signer.pCertInfo = &certInfo;
1029 /* The cert info must contain a serial number and an issuer. */
1030 SetLastError(0xdeadbeef);
1031 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1033 ok(!msg && GetLastError() == E_INVALIDARG,
1034 "Expected E_INVALIDARG, got %x\n", GetLastError());
1035 certInfo.SerialNumber.cbData = sizeof(serialNum);
1036 certInfo.SerialNumber.pbData = serialNum;
1037 SetLastError(0xdeadbeef);
1038 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1040 ok(!msg && GetLastError() == E_INVALIDARG,
1041 "Expected E_INVALIDARG, got %x\n", GetLastError());
1042 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1043 certInfo.Issuer.pbData = encodedCommonName;
1044 SetLastError(0xdeadbeef);
1045 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1047 ok(!msg && GetLastError() == E_INVALIDARG,
1048 "Expected E_INVALIDARG, got %x\n", GetLastError());
1050 /* The signer's hCryptProv must be set to something. Whether it's usable
1051 * or not will be checked after the hash algorithm is checked (see next
1054 signer.hCryptProv = 1;
1055 SetLastError(0xdeadbeef);
1056 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1058 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1059 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1060 /* The signer's hash algorithm must also be set. */
1061 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1062 SetLastError(0xdeadbeef);
1063 /* Crashes in advapi32 in wine, don't do it */
1065 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1066 &signInfo, NULL, NULL);
1067 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1068 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1070 /* The signer's hCryptProv must also be valid. */
1071 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1072 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1073 if (!ret && GetLastError() == NTE_EXISTS)
1074 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1076 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1077 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1079 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1082 CryptReleaseContext(signer.hCryptProv, 0);
1083 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1084 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1087 static const BYTE privKey[] = {
1088 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1089 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1090 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1091 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1092 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1093 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1094 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1095 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1096 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1097 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1098 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1099 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1100 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1101 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1102 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1103 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1104 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1105 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1106 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1107 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1108 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1109 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1110 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1111 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1112 static BYTE pubKey[] = {
1113 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1114 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1115 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1116 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1117 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1119 static void test_signed_msg_update(void)
1123 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1124 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1125 CERT_INFO certInfo = { 0 };
1128 certInfo.SerialNumber.cbData = sizeof(serialNum);
1129 certInfo.SerialNumber.pbData = serialNum;
1130 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1131 certInfo.Issuer.pbData = encodedCommonName;
1132 signer.pCertInfo = &certInfo;
1133 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1134 signInfo.cSigners = 1;
1135 signInfo.rgSigners = &signer;
1136 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1137 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1138 if (!ret && GetLastError() == NTE_EXISTS)
1139 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1141 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1142 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1143 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1144 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1145 /* Detached CMSG_SIGNED allows non-final updates. */
1146 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1147 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1148 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1149 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1150 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1151 /* The final update requires a private key in the hCryptProv, in order to
1152 * generate the signature.
1154 SetLastError(0xdeadbeef);
1155 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1156 ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1157 GetLastError() == NTE_NO_KEY),
1158 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1159 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1161 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1162 /* The final update should be able to succeed now that a key exists, but
1163 * the previous (invalid) final update prevents it.
1165 SetLastError(0xdeadbeef);
1166 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1167 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1168 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1171 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1172 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1173 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1174 /* Detached CMSG_SIGNED allows non-final updates. */
1175 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1176 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1177 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1178 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1179 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1180 /* Now that the private key exists, the final update can succeed (even
1183 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1184 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1185 /* But no updates are allowed after the final update. */
1186 SetLastError(0xdeadbeef);
1187 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1188 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1189 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1190 SetLastError(0xdeadbeef);
1191 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1192 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1193 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1196 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1198 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1199 /* Non-detached messages don't allow non-final updates.. */
1200 SetLastError(0xdeadbeef);
1201 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1202 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1203 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1204 /* but they do allow final ones. */
1205 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1206 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1208 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1210 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1211 /* They also allow final updates with no data. */
1212 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1213 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1216 CryptDestroyKey(key);
1217 CryptReleaseContext(signer.hCryptProv, 0);
1218 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1219 CRYPT_DELETEKEYSET);
1222 static const BYTE signedEmptyBareContent[] = {
1223 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1224 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1225 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1226 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1227 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1228 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1229 static const BYTE signedEmptyContent[] = {
1230 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1231 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1232 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1233 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1234 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1235 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1236 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1237 static const BYTE detachedSignedBareContent[] = {
1238 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1239 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1240 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1241 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1242 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1243 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1244 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1245 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1246 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1247 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1248 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1249 static const BYTE detachedSignedContent[] = {
1250 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1251 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1252 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1253 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1254 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1255 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1256 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1257 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1258 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1259 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1260 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1261 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1262 static const BYTE signedBareContent[] = {
1263 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1264 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1265 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1266 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1267 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1268 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1269 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1270 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1271 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1272 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1273 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1274 static const BYTE signedContent[] = {
1275 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1276 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1277 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1278 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1279 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1280 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1281 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1282 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1283 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1284 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1285 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1286 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1288 static const BYTE signedHash[] = {
1289 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1291 static const BYTE signedEncodedSigner[] = {
1292 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1293 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1294 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1295 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1296 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1297 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1298 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1299 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1300 static const BYTE signedWithAuthAttrsBareContent[] = {
1301 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1302 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1303 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1304 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1305 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1306 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1307 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1308 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1309 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1310 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1311 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1312 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1313 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1314 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1315 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1316 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1317 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1318 0xff,0xc6,0x33,0x63,0x34 };
1319 static BYTE cert[] = {
1320 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1321 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1322 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1323 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1324 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1325 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1326 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1327 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1328 0xff,0x02,0x01,0x01 };
1329 static BYTE v1CertWithPubKey[] = {
1330 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1331 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1332 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1333 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1334 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1335 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1336 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1337 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1338 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1339 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1341 static const BYTE signedWithCertEmptyBareContent[] = {
1342 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1343 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1344 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1345 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1346 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1347 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1348 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1349 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1350 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1351 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1352 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1353 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1354 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1355 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1356 static const BYTE signedWithCertBareContent[] = {
1357 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1358 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1359 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1360 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1361 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1362 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1363 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1364 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1365 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1366 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1367 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1368 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1369 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1370 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1371 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1372 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1373 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1374 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1375 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1376 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1377 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1378 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1379 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1380 0x30,0x30,0x30,0x30,0x5a };
1381 static const BYTE signedWithCrlEmptyBareContent[] = {
1382 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1383 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1384 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1385 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1386 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1387 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1388 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1389 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1390 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1391 static const BYTE signedWithCrlBareContent[] = {
1392 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1393 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1394 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1395 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1396 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1397 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1398 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1399 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1400 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1401 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1402 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1403 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1404 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1405 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1407 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1408 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1409 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1410 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1411 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1412 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1413 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1414 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1415 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1416 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1417 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1418 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1419 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1420 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1421 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1422 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1423 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1424 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1426 static const BYTE signedWithCertAndCrlBareContent[] = {
1427 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1428 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1429 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1430 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1431 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1432 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1433 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1434 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1435 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1436 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1437 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1438 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1439 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1440 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1441 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1442 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1443 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1444 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1445 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1446 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1447 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1448 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1449 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1450 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1451 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1452 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1453 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1454 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1455 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1456 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1457 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1458 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1459 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1460 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1461 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1462 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1463 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1464 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1465 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1466 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1467 static BYTE v1CertWithValidPubKey[] = {
1468 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1469 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1470 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1471 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1472 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1473 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1474 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1475 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1476 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1477 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1478 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1479 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1480 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1481 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1482 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1483 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1484 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1485 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1486 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1487 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1488 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1489 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1490 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1491 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1492 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1493 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1494 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1495 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1496 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1497 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1498 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1499 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1500 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1501 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1502 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1503 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1505 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1506 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1507 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1508 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1509 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1510 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1511 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1512 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1513 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1514 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1515 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1516 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1517 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1518 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1519 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1520 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1521 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1522 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1523 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1524 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1525 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1526 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1527 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1528 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1529 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1530 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1531 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1532 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1534 static void test_signed_msg_encoding(void)
1537 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1538 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1539 CERT_INFO certInfo = { 0 };
1540 CERT_BLOB encodedCert = { sizeof(cert), cert };
1541 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1542 char oid_common_name[] = szOID_COMMON_NAME;
1543 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1544 encodedCommonName };
1545 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1550 certInfo.SerialNumber.cbData = sizeof(serialNum);
1551 certInfo.SerialNumber.pbData = serialNum;
1552 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1553 certInfo.Issuer.pbData = encodedCommonName;
1554 signer.pCertInfo = &certInfo;
1555 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1556 signInfo.cSigners = 1;
1557 signInfo.rgSigners = &signer;
1558 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1559 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1560 if (!ret && GetLastError() == NTE_EXISTS)
1561 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1563 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1564 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1566 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1568 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1569 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1570 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1572 check_param("detached signed empty bare content", msg,
1573 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1574 sizeof(signedEmptyBareContent));
1575 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1576 signedEmptyContent, sizeof(signedEmptyContent));
1577 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1578 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1579 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1580 signedHash, sizeof(signedHash));
1581 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1582 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1583 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1584 detachedSignedContent, sizeof(detachedSignedContent));
1585 SetLastError(0xdeadbeef);
1586 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1587 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1588 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1589 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1590 signedEncodedSigner, sizeof(signedEncodedSigner));
1594 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1596 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1598 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1599 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1600 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1601 signedEmptyContent, sizeof(signedEmptyContent));
1602 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1603 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1604 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1605 signedBareContent, sizeof(signedBareContent));
1606 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1607 signedContent, sizeof(signedContent));
1611 signer.cAuthAttr = 1;
1612 signer.rgAuthAttr = &attr;
1613 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1615 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1617 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1618 check_param("signed with auth attrs bare content", msg,
1619 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1620 sizeof(signedWithAuthAttrsBareContent));
1624 signer.cAuthAttr = 0;
1625 signInfo.rgCertEncoded = &encodedCert;
1626 signInfo.cCertEncoded = 1;
1627 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1629 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1631 check_param("signed with cert empty bare content", msg,
1632 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1633 sizeof(signedWithCertEmptyBareContent));
1634 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1635 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1636 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1637 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1641 signInfo.cCertEncoded = 0;
1642 signInfo.rgCrlEncoded = &encodedCrl;
1643 signInfo.cCrlEncoded = 1;
1644 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1646 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1648 check_param("signed with crl empty bare content", msg,
1649 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1650 sizeof(signedWithCrlEmptyBareContent));
1651 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1652 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1653 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1654 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1658 signInfo.cCertEncoded = 1;
1659 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1661 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1663 check_param("signed with cert and crl empty bare content", msg,
1664 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1665 sizeof(signedWithCertAndCrlEmptyBareContent));
1666 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1667 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1668 check_param("signed with cert and crl bare content", msg,
1669 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1670 sizeof(signedWithCertAndCrlBareContent));
1674 /* Test with a cert with a (bogus) public key */
1675 signInfo.cCrlEncoded = 0;
1676 encodedCert.cbData = sizeof(v1CertWithPubKey);
1677 encodedCert.pbData = v1CertWithPubKey;
1678 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1680 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1681 check_param("signedWithCertWithPubKeyBareContent", msg,
1682 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1683 sizeof(signedWithCertWithPubKeyBareContent));
1686 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1687 encodedCert.pbData = v1CertWithValidPubKey;
1688 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1690 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1691 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1692 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1693 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1694 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1695 check_param("signedWithCertWithValidPubKeyContent", msg,
1696 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1697 sizeof(signedWithCertWithValidPubKeyContent));
1700 CryptDestroyKey(key);
1701 CryptReleaseContext(signer.hCryptProv, 0);
1702 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1703 CRYPT_DELETEKEYSET);
1706 static void test_signed_msg_get_param(void)
1710 DWORD size, value = 0;
1711 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1712 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1713 CERT_INFO certInfo = { 0 };
1715 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1717 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1719 /* Content and bare content are always gettable */
1721 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1722 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1724 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1725 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1726 /* For "signed" messages, so is the version. */
1728 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1729 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1730 size = sizeof(value);
1731 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1732 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1733 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1734 /* But for this message, with no signers, the hash and signer aren't
1738 SetLastError(0xdeadbeef);
1739 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1740 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1741 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1742 SetLastError(0xdeadbeef);
1743 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1744 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1745 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1746 /* As usual, the type isn't available. */
1747 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1748 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1749 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1753 certInfo.SerialNumber.cbData = sizeof(serialNum);
1754 certInfo.SerialNumber.pbData = serialNum;
1755 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1756 certInfo.Issuer.pbData = encodedCommonName;
1757 signer.pCertInfo = &certInfo;
1758 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1759 signInfo.cSigners = 1;
1760 signInfo.rgSigners = &signer;
1761 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1762 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1763 if (!ret && GetLastError() == NTE_EXISTS)
1764 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1766 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1767 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1769 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1771 /* This message, with one signer, has the hash and signer for index 0
1772 * available, but not for other indexes.
1775 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1776 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1777 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1778 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1780 SetLastError(0xdeadbeef);
1781 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1782 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1783 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1784 SetLastError(0xdeadbeef);
1785 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1786 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1787 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1788 /* As usual, the type isn't available. */
1789 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1790 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1791 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1795 CryptReleaseContext(signer.hCryptProv, 0);
1796 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1797 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1800 static void test_signed_msg(void)
1802 test_signed_msg_open();
1803 test_signed_msg_update();
1804 test_signed_msg_encoding();
1805 test_signed_msg_get_param();
1808 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1809 static const struct update_accum a4 = { 1, &b4 };
1811 static const BYTE bogusOIDContent[] = {
1812 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1814 static const BYTE bogusHashContent[] = {
1815 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1816 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1817 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1818 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1819 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1821 static void test_decode_msg_update(void)
1825 CMSG_STREAM_INFO streamInfo = { 0 };
1827 struct update_accum accum = { 0, NULL };
1829 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1830 /* Update with a full message in a final update */
1831 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1832 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1833 /* Can't update after a final update */
1834 SetLastError(0xdeadbeef);
1835 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1836 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1837 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1840 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1841 /* Can't send a non-final update without streaming */
1842 SetLastError(0xdeadbeef);
1843 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1845 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1846 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1847 /* A subsequent final update succeeds */
1848 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1849 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1852 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1853 /* Updating a message that has a NULL stream callback fails */
1854 SetLastError(0xdeadbeef);
1855 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1858 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1859 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1860 /* Changing the callback pointer after the fact yields the same error (so
1861 * the message must copy the stream info, not just store a pointer to it)
1863 streamInfo.pfnStreamOutput = nop_stream_output;
1864 SetLastError(0xdeadbeef);
1865 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1868 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1869 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1872 /* Empty non-final updates are allowed when streaming.. */
1873 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1874 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1875 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1876 /* but final updates aren't when not enough data has been received. */
1877 SetLastError(0xdeadbeef);
1878 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1880 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1881 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1884 /* Updating the message byte by byte is legal */
1885 streamInfo.pfnStreamOutput = accumulating_stream_output;
1886 streamInfo.pvArg = &accum;
1887 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1888 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1889 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1890 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1891 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1892 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1895 check_updates("byte-by-byte empty content", &a4, &accum);
1896 free_updates(&accum);
1898 /* Decoding bogus content fails in non-streaming mode.. */
1899 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1900 SetLastError(0xdeadbeef);
1901 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1902 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1903 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1905 /* and as the final update in streaming mode.. */
1906 streamInfo.pfnStreamOutput = nop_stream_output;
1907 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1908 SetLastError(0xdeadbeef);
1909 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1911 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1912 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1914 /* and even as a non-final update in streaming mode. */
1915 streamInfo.pfnStreamOutput = nop_stream_output;
1916 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1917 SetLastError(0xdeadbeef);
1918 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1920 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1921 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1924 /* An empty message can be opened with undetermined type.. */
1925 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1926 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1928 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1930 /* but decoding it as an explicitly typed message fails. */
1931 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1933 SetLastError(0xdeadbeef);
1934 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1936 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1937 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1939 /* On the other hand, decoding the bare content of an empty message fails
1940 * with unspecified type..
1942 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1943 SetLastError(0xdeadbeef);
1944 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1945 sizeof(dataEmptyBareContent), TRUE);
1946 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1947 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1949 /* but succeeds with explicit type. */
1950 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1952 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1953 sizeof(dataEmptyBareContent), TRUE);
1954 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1957 /* Decoding valid content with an unsupported OID fails */
1958 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1959 SetLastError(0xdeadbeef);
1960 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
1961 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1962 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1965 /* Similarly, opening an empty hash with unspecified type succeeds.. */
1966 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1967 SetLastError(0xdeadbeef);
1968 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1969 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1971 /* while with specified type it fails. */
1972 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1974 SetLastError(0xdeadbeef);
1975 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1976 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1977 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1979 /* On the other hand, decoding the bare content of an empty hash message
1980 * fails with unspecified type..
1982 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1983 SetLastError(0xdeadbeef);
1984 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1985 sizeof(hashEmptyBareContent), TRUE);
1986 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1987 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1989 /* but succeeds with explicit type. */
1990 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1992 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1993 sizeof(hashEmptyBareContent), TRUE);
1994 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1997 /* And again, opening a (non-empty) hash message with unspecified type
2000 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2001 SetLastError(0xdeadbeef);
2002 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2003 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2005 /* while with specified type it fails.. */
2006 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2008 SetLastError(0xdeadbeef);
2009 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2010 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2011 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2013 /* and decoding the bare content of a non-empty hash message fails with
2014 * unspecified type..
2016 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2017 SetLastError(0xdeadbeef);
2018 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2019 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2020 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2022 /* but succeeds with explicit type. */
2023 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2025 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2026 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2029 /* Opening a (non-empty) hash message with unspecified type and a bogus
2030 * hash value succeeds..
2032 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2033 SetLastError(0xdeadbeef);
2034 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2035 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2038 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2039 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2040 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2042 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2043 SetLastError(0xdeadbeef);
2044 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2045 sizeof(signedWithCertAndCrlBareContent), TRUE);
2046 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2047 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2049 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2051 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2052 sizeof(signedWithCertAndCrlBareContent), TRUE);
2053 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2056 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2058 /* The first update succeeds.. */
2059 ret = CryptMsgUpdate(msg, detachedSignedContent,
2060 sizeof(detachedSignedContent), TRUE);
2061 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2062 /* as does a second (probably to update the detached portion).. */
2063 ret = CryptMsgUpdate(msg, detachedSignedContent,
2064 sizeof(detachedSignedContent), TRUE);
2065 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2066 /* while a third fails. */
2067 ret = CryptMsgUpdate(msg, detachedSignedContent,
2068 sizeof(detachedSignedContent), TRUE);
2069 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2070 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2074 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2075 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2077 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2078 const CMSG_SIGNER_INFO *expected)
2080 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2081 expected->dwVersion, got->dwVersion);
2082 ok(got->Issuer.cbData == expected->Issuer.cbData,
2083 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2084 got->Issuer.cbData);
2085 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2086 "Unexpected issuer\n");
2087 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2088 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2089 got->SerialNumber.cbData);
2090 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2091 got->SerialNumber.cbData), "Unexpected serial number\n");
2092 /* FIXME: check more things */
2095 static const BYTE signedWithCertAndCrlComputedHash[] = {
2096 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2099 static void test_decode_msg_get_param(void)
2103 DWORD size = 0, value;
2106 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2107 SetLastError(0xdeadbeef);
2108 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2109 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2110 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2111 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2112 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2116 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2117 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2118 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2119 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2120 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2121 emptyHashParam, sizeof(emptyHashParam));
2123 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2124 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2125 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2127 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2129 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2130 hashParam, sizeof(hashParam));
2131 /* Curiously, getting the hash of index 1 succeeds, even though there's
2134 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2135 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2136 buf = CryptMemAlloc(size);
2139 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2140 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2141 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2144 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2145 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2146 value = CMSG_HASHED_DATA_V0;
2147 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2151 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2152 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2153 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2154 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2156 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2157 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2158 size = sizeof(value);
2160 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2161 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2162 ok(value == 1, "Expected 1 signer, got %d\n", value);
2164 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2165 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2167 buf = CryptMemAlloc(size);
2172 CMSG_SIGNER_INFO signer = { 0 };
2174 signer.dwVersion = 1;
2175 signer.Issuer.cbData = sizeof(encodedCommonName);
2176 signer.Issuer.pbData = encodedCommonName;
2177 signer.SerialNumber.cbData = sizeof(serialNum);
2178 signer.SerialNumber.pbData = serialNum;
2179 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2180 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2181 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2184 /* index is ignored when getting signer count */
2185 size = sizeof(value);
2186 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2187 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2188 ok(value == 1, "Expected 1 signer, got %d\n", value);
2189 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2190 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2191 ok(value == 0, "Expected 0 certs, got %d\n", value);
2192 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2193 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2194 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2196 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2198 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2199 sizeof(signedWithCertAndCrlBareContent), TRUE);
2200 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2201 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2202 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2203 ok(value == 1, "Expected 1 cert, got %d\n", value);
2204 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2205 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2206 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2207 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2208 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2209 check_param("signed with cert and CRL computed hash", msg,
2210 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2211 sizeof(signedWithCertAndCrlComputedHash));
2215 static void test_decode_msg(void)
2217 test_decode_msg_update();
2218 test_decode_msg_get_param();
2221 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2222 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2223 static BYTE encodedPubKey[] = {
2224 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2225 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2227 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2228 static BYTE mod_encoded[] = {
2229 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2232 static void test_msg_control(void)
2234 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2238 CERT_INFO certInfo = { 0 };
2239 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2240 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2241 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2244 ret = CryptMsgControl(NULL, 0, 0, NULL);
2247 /* Data encode messages don't allow any sort of control.. */
2248 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2250 /* either with no prior update.. */
2251 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2253 SetLastError(0xdeadbeef);
2254 ret = CryptMsgControl(msg, 0, i, NULL);
2255 ok(!ret && GetLastError() == E_INVALIDARG,
2256 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2258 /* or after an update. */
2259 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2261 SetLastError(0xdeadbeef);
2262 ret = CryptMsgControl(msg, 0, i, NULL);
2263 ok(!ret && GetLastError() == E_INVALIDARG,
2264 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2268 /* Hash encode messages don't allow any sort of control.. */
2269 hashInfo.cbSize = sizeof(hashInfo);
2270 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2271 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2273 /* either with no prior update.. */
2274 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2276 SetLastError(0xdeadbeef);
2277 ret = CryptMsgControl(msg, 0, i, NULL);
2278 ok(!ret && GetLastError() == E_INVALIDARG,
2279 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2281 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2282 /* or after an update. */
2283 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2285 SetLastError(0xdeadbeef);
2286 ret = CryptMsgControl(msg, 0, i, NULL);
2287 ok(!ret && GetLastError() == E_INVALIDARG,
2288 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2292 /* Signed encode messages likewise don't allow any sort of control.. */
2293 signInfo.cbSize = sizeof(signInfo);
2294 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2296 /* either before an update.. */
2297 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2299 SetLastError(0xdeadbeef);
2300 ret = CryptMsgControl(msg, 0, i, NULL);
2301 ok(!ret && GetLastError() == E_INVALIDARG,
2302 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2304 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2305 /* or after an update. */
2306 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2308 SetLastError(0xdeadbeef);
2309 ret = CryptMsgControl(msg, 0, i, NULL);
2310 ok(!ret && GetLastError() == E_INVALIDARG,
2311 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2315 /* Decode messages behave a bit differently. */
2316 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2317 /* Bad control type */
2318 SetLastError(0xdeadbeef);
2319 ret = CryptMsgControl(msg, 0, 0, NULL);
2320 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2321 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2322 SetLastError(0xdeadbeef);
2323 ret = CryptMsgControl(msg, 1, 0, NULL);
2324 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2325 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2326 /* Can't verify the hash of an indeterminate-type message */
2327 SetLastError(0xdeadbeef);
2328 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2329 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2330 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2332 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2334 /* Can't decrypt an indeterminate-type message */
2335 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2336 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2337 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2340 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2342 /* Can't verify the hash of an empty message */
2343 SetLastError(0xdeadbeef);
2344 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2346 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2347 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2349 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2351 /* Can't verify the signature of a hash message */
2352 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2353 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2354 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2355 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2357 /* Oddly enough, this fails */
2358 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2360 ok(!ret, "Expected failure\n");
2362 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2364 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2365 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2366 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2367 /* Can't decrypt an indeterminate-type message */
2368 SetLastError(0xdeadbeef);
2369 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2370 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2371 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2374 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2376 /* Can't verify the hash of a signed message */
2377 SetLastError(0xdeadbeef);
2378 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2379 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2380 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2381 /* Can't decrypt a signed message */
2382 SetLastError(0xdeadbeef);
2383 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2384 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2385 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2387 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2388 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2390 CryptMsgUpdate(msg, signedWithCertBareContent,
2391 sizeof(signedWithCertBareContent), TRUE);
2392 /* With an empty cert info, the signer can't be found in the message (and
2393 * the signature can't be verified.
2395 SetLastError(0xdeadbeef);
2396 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2397 ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2398 "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2399 /* The cert info is expected to have an issuer, serial number, and public
2402 certInfo.SerialNumber.cbData = sizeof(serialNum);
2403 certInfo.SerialNumber.pbData = serialNum;
2404 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2405 certInfo.Issuer.pbData = encodedCommonName;
2406 SetLastError(0xdeadbeef);
2407 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2408 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2409 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2411 /* This cert has a public key, but it's not in a usable form */
2412 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2414 CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2415 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2416 /* Again, cert info needs to have a public key set */
2417 SetLastError(0xdeadbeef);
2418 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2419 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2420 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2421 /* The public key is supposed to be in encoded form.. */
2422 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2423 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2424 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2425 SetLastError(0xdeadbeef);
2426 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2427 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2428 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2429 /* but not as a X509_PUBLIC_KEY_INFO.. */
2430 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2431 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2432 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2433 SetLastError(0xdeadbeef);
2434 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2435 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2436 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2437 /* This decodes successfully, but it doesn't match any key in the message */
2438 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2439 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2440 SetLastError(0xdeadbeef);
2441 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2442 /* In Wine's rsaenh, this fails to decode because the key length is too
2443 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
2447 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2448 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2450 /* A message with no data doesn't have a valid signature */
2451 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2452 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2453 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2454 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2455 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2456 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2457 SetLastError(0xdeadbeef);
2458 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2459 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2460 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2462 /* Finally, this succeeds */
2463 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2464 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2465 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2466 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2467 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2471 static void test_msg_get_signer_count(void)
2475 SetLastError(0xdeadbeef);
2476 count = CryptGetMessageSignerCount(0, NULL, 0);
2477 ok(count == -1, "Expected -1, got %d\n", count);
2478 ok(GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n",
2480 SetLastError(0xdeadbeef);
2481 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, NULL, 0);
2482 ok(count == -1, "Expected -1, got %d\n", count);
2483 ok(GetLastError() == CRYPT_E_ASN1_EOD,
2484 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2485 SetLastError(0xdeadbeef);
2486 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2487 dataEmptyBareContent, sizeof(dataEmptyBareContent));
2488 ok(count == -1, "Expected -1, got %d\n", count);
2489 ok(GetLastError() == CRYPT_E_ASN1_BADTAG,
2490 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2491 SetLastError(0xdeadbeef);
2492 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2493 dataEmptyContent, sizeof(dataEmptyContent));
2494 ok(count == -1, "Expected -1, got %d\n", count);
2495 ok(GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2496 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2497 SetLastError(0xdeadbeef);
2498 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2499 signedEmptyBareContent, sizeof(signedEmptyBareContent));
2500 ok(count == -1, "Expected -1, got %d\n", count);
2501 ok(GetLastError() == CRYPT_E_ASN1_BADTAG,
2502 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2503 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2504 signedEmptyContent, sizeof(signedEmptyContent));
2505 ok(count == 1, "Expected 1, got %d\n", count);
2508 static const BYTE signedWithCertEmptyContent[] = {
2509 0x30,0x81,0xdf,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
2510 0x81,0xd1,0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
2511 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,
2512 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2513 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2514 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2515 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2516 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2517 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2518 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
2519 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2520 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
2521 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
2522 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
2523 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
2525 static const BYTE signedWithCertContent[] = {
2526 0x30,0x82,0x01,0x32,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
2527 0xa0,0x82,0x01,0x23,0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
2528 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
2529 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
2530 0x02,0x03,0x04,0xa0,0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
2531 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
2532 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
2533 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
2534 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
2535 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
2536 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
2537 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
2538 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,
2539 0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,
2540 0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,
2541 0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,
2542 0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,
2543 0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,
2544 0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,
2545 0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,
2546 0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
2547 static const BYTE signedWithCertWithPubKeyContent[] = {
2548 0x30,0x81,0xfc,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
2549 0x81,0xee,0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
2550 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,
2551 0x98,0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,
2552 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
2553 0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2554 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
2555 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,
2556 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2557 0x6e,0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2558 0x01,0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
2559 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,
2560 0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,
2561 0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
2562 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2563 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
2564 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
2566 static void test_verify_message_signature(void)
2569 CRYPT_VERIFY_MESSAGE_PARA para = { 0 };
2570 PCCERT_CONTEXT cert;
2573 SetLastError(0xdeadbeef);
2574 ret = CryptVerifyMessageSignature(NULL, 0, NULL, 0, NULL, 0, NULL);
2575 ok(!ret && GetLastError() == E_INVALIDARG,
2576 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2577 SetLastError(0xdeadbeef);
2578 ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL);
2579 ok(!ret && GetLastError() == E_INVALIDARG,
2580 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2581 para.cbSize = sizeof(para);
2582 SetLastError(0xdeadbeef);
2583 ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL);
2584 ok(!ret && GetLastError() == E_INVALIDARG,
2585 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2587 para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING;
2588 SetLastError(0xdeadbeef);
2589 ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL);
2590 ok(!ret && GetLastError() == E_INVALIDARG,
2591 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2592 para.cbSize = sizeof(para);
2593 SetLastError(0xdeadbeef);
2594 ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL);
2595 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2596 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2597 /* Check whether cert is set on error */
2598 cert = (PCCERT_CONTEXT)0xdeadbeef;
2599 ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, &cert);
2600 ok(cert == NULL, "Expected NULL cert\n");
2601 /* Check whether cbDecoded is set on error */
2602 cbDecoded = 0xdeadbeef;
2603 ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, &cbDecoded,
2605 ok(!cbDecoded, "Expected 0\n");
2606 SetLastError(0xdeadbeef);
2607 ret = CryptVerifyMessageSignature(¶, 0, dataEmptyBareContent,
2608 sizeof(dataEmptyBareContent), NULL, 0, NULL);
2609 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2610 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2611 SetLastError(0xdeadbeef);
2612 ret = CryptVerifyMessageSignature(¶, 0, dataEmptyContent,
2613 sizeof(dataEmptyContent), NULL, 0, NULL);
2614 ok(!ret && GetLastError() == CRYPT_E_UNEXPECTED_MSG_TYPE,
2615 "Expected CRYPT_E_UNEXPECTED_MSG_TYPE, got %08x\n", GetLastError());
2616 SetLastError(0xdeadbeef);
2617 ret = CryptVerifyMessageSignature(¶, 0, signedEmptyBareContent,
2618 sizeof(signedEmptyBareContent), NULL, 0, NULL);
2619 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2620 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2621 SetLastError(0xdeadbeef);
2622 ret = CryptVerifyMessageSignature(¶, 0, signedEmptyContent,
2623 sizeof(signedEmptyContent), NULL, 0, NULL);
2624 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2625 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2626 SetLastError(0xdeadbeef);
2627 ret = CryptVerifyMessageSignature(¶, 0, signedContent,
2628 sizeof(signedContent), NULL, 0, NULL);
2629 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2630 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2631 /* FIXME: Windows fails with CRYPT_E_NOT_FOUND for these messages, but
2632 * their signer certs have invalid public keys that fail to decode. In
2633 * Wine therefore the failure is an ASN error. Need some messages with
2634 * valid public keys and invalid signatures to check against.
2636 ret = CryptVerifyMessageSignature(¶, 0, signedWithCertEmptyContent,
2637 sizeof(signedWithCertEmptyContent), NULL, 0, NULL);
2638 ok(!ret, "Expected failure\n");
2639 ret = CryptVerifyMessageSignature(¶, 0, signedWithCertContent,
2640 sizeof(signedWithCertContent), NULL, 0, NULL);
2641 ok(!ret, "Expected failure\n");
2642 ret = CryptVerifyMessageSignature(¶, 0, signedWithCertWithPubKeyContent,
2643 sizeof(signedWithCertWithPubKeyContent), NULL, 0, NULL);
2644 ok(!ret, "Expected failure\n");
2649 init_function_pointers();
2651 /* Basic parameter checking tests */
2652 test_msg_open_to_encode();
2653 test_msg_open_to_decode();
2654 test_msg_get_param();
2658 /* Message-type specific tests */
2664 /* simplified message functions */
2665 test_msg_get_signer_count();
2666 test_verify_message_signature();