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"
31 static char oid_rsa_md5[] = szOID_RSA_MD5;
33 static BOOL (WINAPI * pCryptAcquireContextA)
34 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
35 static BOOL (WINAPI * pCryptAcquireContextW)
36 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
38 static void init_function_pointers(void)
40 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
42 #define GET_PROC(dll, func) \
43 p ## func = (void *)GetProcAddress(dll, #func); \
45 trace("GetProcAddress(%s) failed\n", #func);
47 GET_PROC(hAdvapi32, CryptAcquireContextA)
48 GET_PROC(hAdvapi32, CryptAcquireContextW)
53 static void test_msg_open_to_encode(void)
58 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
60 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
62 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
67 SetLastError(0xdeadbeef);
68 msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
69 ok(!msg && GetLastError() == E_INVALIDARG,
70 "Expected E_INVALIDARG, got %x\n", GetLastError());
71 SetLastError(0xdeadbeef);
72 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
73 ok(!msg && GetLastError() == E_INVALIDARG,
74 "Expected E_INVALIDARG, got %x\n", GetLastError());
76 /* Bad message types */
77 SetLastError(0xdeadbeef);
78 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
79 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
80 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
81 SetLastError(0xdeadbeef);
82 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
84 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
85 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
86 SetLastError(0xdeadbeef);
87 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
88 CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
89 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
90 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
91 SetLastError(0xdeadbeef);
92 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
94 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
95 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
98 static void test_msg_open_to_decode(void)
101 CMSG_STREAM_INFO streamInfo = { 0 };
103 SetLastError(0xdeadbeef);
104 msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
105 ok(!msg && GetLastError() == E_INVALIDARG,
106 "Expected E_INVALIDARG, got %x\n", GetLastError());
109 SetLastError(0xdeadbeef);
110 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
111 ok(!msg && GetLastError() == E_INVALIDARG,
112 "Expected E_INVALIDARG, got %x\n", GetLastError());
113 SetLastError(0xdeadbeef);
114 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
115 ok(!msg && GetLastError() == E_INVALIDARG,
116 "Expected E_INVALIDARG, got %x\n", GetLastError());
118 /* The message type can be explicit... */
119 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
121 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
123 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
125 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
127 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
129 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
131 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
133 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
135 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
136 CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
137 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
140 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
141 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
143 /* or even invalid. */
144 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
146 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
148 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
149 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
152 /* And even though the stream info parameter "must be set to NULL" for
153 * CMSG_HASHED, it's still accepted.
155 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
157 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
161 static void test_msg_get_param(void)
165 DWORD size, i, value;
166 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
167 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
170 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
171 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
172 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
175 /* Decoded messages */
176 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
177 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
178 /* For decoded messages, the type is always available */
180 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
181 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
182 size = sizeof(value);
183 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
184 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
185 /* For this (empty) message, the type isn't set */
186 ok(value == 0, "Expected type 0, got %d\n", value);
189 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
191 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
192 /* For explicitly typed messages, the type is known. */
193 size = sizeof(value);
194 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
195 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
196 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
197 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
200 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
201 ok(!ret, "Parameter %d: expected failure\n", i);
205 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
207 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
208 size = sizeof(value);
209 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
210 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
211 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
212 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
215 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
216 ok(!ret, "Parameter %d: expected failure\n", i);
220 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
222 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
223 size = sizeof(value);
224 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
225 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
226 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
227 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
230 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
231 ok(!ret, "Parameter %d: expected failure\n", i);
235 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
237 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
238 size = sizeof(value);
239 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
240 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
241 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
242 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
245 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
246 ok(!ret, "Parameter %d: expected failure\n", i);
250 /* Explicitly typed messages get their types set, even if they're invalid */
251 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
253 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
254 size = sizeof(value);
255 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
256 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
257 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
260 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
261 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
262 size = sizeof(value);
263 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
264 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
265 ok(value == 1000, "Expected 1000, got %d\n", value);
269 static void test_msg_close(void)
274 /* NULL succeeds.. */
275 ret = CryptMsgClose(NULL);
276 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
277 /* but an arbitrary pointer crashes. */
279 ret = CryptMsgClose((HCRYPTMSG)1);
280 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
282 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
283 ret = CryptMsgClose(msg);
284 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
287 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
288 const BYTE *expected, DWORD expectedSize)
295 ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
296 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
297 buf = HeapAlloc(GetProcessHeap(), 0, size);
298 ret = CryptMsgGetParam(msg, param, 0, buf, &size);
299 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
300 ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
302 if (size == expectedSize && size)
303 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
304 HeapFree(GetProcessHeap(), 0, buf);
307 static void test_data_msg_open(void)
310 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
311 CMSG_STREAM_INFO streamInfo = { 0 };
312 char oid[] = "1.2.3";
314 /* The data message type takes no additional info */
315 SetLastError(0xdeadbeef);
316 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
318 ok(!msg && GetLastError() == E_INVALIDARG,
319 "Expected E_INVALIDARG, got %x\n", GetLastError());
320 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
322 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
325 /* An empty stream info is allowed. */
326 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
328 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
331 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
332 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
334 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
336 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
337 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
338 CMSG_DATA, NULL, oid, NULL);
339 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
341 /* and when a stream info is given, even though you're not supposed to be
342 * able to use anything but szOID_RSA_data when streaming is being used.
344 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
345 CMSG_DATA, NULL, oid, &streamInfo);
346 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
350 static const BYTE msgData[] = { 1, 2, 3, 4 };
352 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
358 static void test_data_msg_update(void)
362 CMSG_STREAM_INFO streamInfo = { 0 };
364 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
366 /* Can't update a message that wasn't opened detached with final = FALSE */
367 SetLastError(0xdeadbeef);
368 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
369 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
370 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
371 /* Updating it with final = TRUE succeeds */
372 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
373 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
374 /* Any subsequent update will fail, as the last was final */
375 SetLastError(0xdeadbeef);
376 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
377 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
378 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
381 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
383 /* Can't update a message with no data */
384 SetLastError(0xdeadbeef);
385 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
386 /* This test returns FALSE on XP and earlier but TRUE on Vista, so can't be tested.
387 * GetLastError is either E_INVALIDARG (NT) or unset (9x/Vista), so it doesn't
388 * make sense to test this.
391 /* Curiously, a valid update will now fail as well, presumably because of
392 * the last (invalid, but final) update.
394 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
395 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
396 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
399 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
400 CMSG_DATA, NULL, NULL, NULL);
401 /* Doesn't appear to be able to update CMSG-DATA with non-final updates */
402 SetLastError(0xdeadbeef);
403 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
404 ok(!ret && GetLastError() == E_INVALIDARG,
405 "Expected E_INVALIDARG, got %x\n", GetLastError());
406 SetLastError(0xdeadbeef);
407 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
408 ok(!ret && GetLastError() == E_INVALIDARG,
409 "Expected E_INVALIDARG, got %x\n", GetLastError());
410 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
411 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
414 /* Calling update after opening with an empty stream info (with a bogus
415 * output function) yields an error:
417 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
419 SetLastError(0xdeadbeef);
420 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
421 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
422 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
424 /* Calling update with a valid output function succeeds, even if the data
425 * exceeds the size specified in the stream info.
427 streamInfo.pfnStreamOutput = nop_stream_output;
428 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
430 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
431 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
432 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
433 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
437 static void test_data_msg_get_param(void)
442 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
444 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
447 /* Content and bare content are always gettable when not streaming */
449 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
450 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
452 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
453 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
454 /* But for this type of message, the signer and hash aren't applicable,
455 * and the type isn't available.
458 SetLastError(0xdeadbeef);
459 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
460 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
461 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
462 SetLastError(0xdeadbeef);
463 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
464 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
465 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
466 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
467 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
468 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
471 /* Can't get content or bare content when streaming */
472 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
474 SetLastError(0xdeadbeef);
475 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
476 ok(!ret && GetLastError() == E_INVALIDARG,
477 "Expected E_INVALIDARG, got %x\n", GetLastError());
478 SetLastError(0xdeadbeef);
479 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
480 ok(!ret && GetLastError() == E_INVALIDARG,
481 "Expected E_INVALIDARG, got %x\n", GetLastError());
485 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
486 static const BYTE dataEmptyContent[] = {
487 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
489 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
490 static const BYTE dataContent[] = {
491 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
492 0x04,0x04,0x01,0x02,0x03,0x04 };
497 CRYPT_DATA_BLOB *updates;
500 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
501 DWORD cb, BOOL final)
503 struct update_accum *accum = (struct update_accum *)pvArg;
507 accum->updates = CryptMemRealloc(accum->updates,
508 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
510 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
513 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
515 blob->pbData = CryptMemAlloc(cb);
518 memcpy(blob->pbData, pb, cb);
527 /* The updates of a (bogus) definite-length encoded message */
528 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
529 0x07,0x01,0xa0,0x02,0x04,0x00 };
530 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
531 static CRYPT_DATA_BLOB b1[] = {
536 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
537 /* The updates of a definite-length encoded message */
538 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
539 0x07,0x01,0xa0,0x06,0x04,0x04 };
540 static CRYPT_DATA_BLOB b2[] = {
544 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
545 /* The updates of an indefinite-length encoded message */
546 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
547 0x07,0x01,0xa0,0x80,0x24,0x80 };
548 static BYTE u5[] = { 0x04,0x04 };
549 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
550 static CRYPT_DATA_BLOB b3[] = {
558 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
560 static void check_updates(LPCSTR header, const struct update_accum *expected,
561 const struct update_accum *got)
565 ok(expected->cUpdates == got->cUpdates,
566 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
568 if (expected->cUpdates == got->cUpdates)
569 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
571 ok(expected->updates[i].cbData == got->updates[i].cbData,
572 "%s, update %d: expected %d bytes, got %d\n", header, i,
573 expected->updates[i].cbData, got->updates[i].cbData);
574 if (expected->updates[i].cbData && expected->updates[i].cbData ==
575 got->updates[i].cbData)
576 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
577 got->updates[i].cbData), "%s, update %d: unexpected value\n",
582 /* Frees the updates stored in accum */
583 static void free_updates(struct update_accum *accum)
587 for (i = 0; i < accum->cUpdates; i++)
588 CryptMemFree(accum->updates[i].pbData);
589 CryptMemFree(accum->updates);
590 accum->updates = NULL;
594 static void test_data_msg_encoding(void)
598 static char oid[] = "1.2.3";
599 struct update_accum accum = { 0, NULL };
600 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
602 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
604 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
605 dataEmptyBareContent, sizeof(dataEmptyBareContent));
606 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
607 sizeof(dataEmptyContent));
608 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
609 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
610 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
611 dataBareContent, sizeof(dataBareContent));
612 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
613 sizeof(dataContent));
615 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
616 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
617 CMSG_DATA, NULL, NULL, NULL);
618 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
619 dataEmptyBareContent, sizeof(dataEmptyBareContent));
620 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
621 sizeof(dataEmptyContent));
622 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
623 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
624 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
625 dataBareContent, sizeof(dataBareContent));
626 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
627 sizeof(dataContent));
629 /* The inner OID is apparently ignored */
630 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
632 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
633 dataEmptyBareContent, sizeof(dataEmptyBareContent));
634 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
635 dataEmptyContent, sizeof(dataEmptyContent));
636 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
637 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
638 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
639 dataBareContent, sizeof(dataBareContent));
640 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
641 sizeof(dataContent));
643 /* A streaming message is DER encoded if the length is not 0xffffffff, but
644 * curiously, updates aren't validated to make sure they don't exceed the
645 * stated length. (The resulting output will of course fail to decode.)
647 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
649 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
650 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
652 check_updates("bogus data message with definite length", &a1, &accum);
653 free_updates(&accum);
654 /* A valid definite-length encoding: */
655 streamInfo.cbContent = sizeof(msgData);
656 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
658 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
660 check_updates("data message with definite length", &a2, &accum);
661 free_updates(&accum);
662 /* An indefinite-length encoding: */
663 streamInfo.cbContent = 0xffffffff;
664 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
666 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
667 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
669 check_updates("data message with indefinite length", &a3, &accum);
670 free_updates(&accum);
673 static void test_data_msg(void)
675 test_data_msg_open();
676 test_data_msg_update();
677 test_data_msg_get_param();
678 test_data_msg_encoding();
681 static void test_hash_msg_open(void)
684 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
685 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
687 SetLastError(0xdeadbeef);
688 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
690 ok(!msg && GetLastError() == E_INVALIDARG,
691 "Expected E_INVALIDARG, got %x\n", GetLastError());
692 hashInfo.cbSize = sizeof(hashInfo);
693 SetLastError(0xdeadbeef);
694 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
696 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
697 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
698 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
699 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
701 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
703 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
704 CMSG_HASHED, &hashInfo, NULL, NULL);
705 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
707 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
708 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
709 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
713 static void test_hash_msg_update(void)
717 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
718 { oid_rsa_md5, { 0, NULL } }, NULL };
719 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
721 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
722 CMSG_HASHED, &hashInfo, NULL, NULL);
723 /* Detached hashed messages opened in non-streaming mode allow non-final
726 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
727 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
728 /* including non-final updates with no data.. */
729 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
730 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
731 /* and final updates with no data. */
732 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
733 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
734 /* But no updates are allowed after the final update. */
735 SetLastError(0xdeadbeef);
736 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
737 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
738 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
739 SetLastError(0xdeadbeef);
740 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
741 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
742 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
744 /* Non-detached messages, in contrast, don't allow non-final updates in
745 * non-streaming mode.
747 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
749 SetLastError(0xdeadbeef);
750 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
751 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
752 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
753 /* Final updates (including empty ones) are allowed. */
754 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
755 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
757 /* And, of course, streaming mode allows non-final updates */
758 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
760 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
761 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
763 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
764 * to be a bug, it isn't actually used - see encoding tests.)
766 streamInfo.pfnStreamOutput = NULL;
767 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
769 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
770 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
774 static const BYTE emptyHashParam[] = {
775 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
778 static void test_hash_msg_get_param(void)
782 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
783 { oid_rsa_md5, { 0, NULL } }, NULL };
785 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
788 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
790 /* Content and bare content are always gettable for non-streamed messages */
792 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
793 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
795 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
796 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
797 /* For an encoded hash message, the hash data aren't available */
798 SetLastError(0xdeadbeef);
799 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
800 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
801 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
802 /* The hash is also available. */
804 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
805 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
806 ok(size == sizeof(buf), "Unexpected size %d\n", size);
807 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
808 if (size == sizeof(buf))
809 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
810 /* By getting the hash, further updates are not allowed */
811 SetLastError(0xdeadbeef);
812 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
814 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
815 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
816 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */),
817 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
819 /* Even after a final update, the hash data aren't available */
820 SetLastError(0xdeadbeef);
821 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
822 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
823 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
824 /* The version is also available, and should be zero for this message. */
826 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
827 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
828 size = sizeof(value);
829 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
830 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
831 ok(value == 0, "Expected version 0, got %d\n", value);
832 /* As usual, the type isn't available. */
833 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
834 ok(!ret, "Expected failure\n");
837 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
839 /* Streamed messages don't allow you to get the content or bare content. */
840 SetLastError(0xdeadbeef);
841 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
842 ok(!ret && GetLastError() == E_INVALIDARG,
843 "Expected E_INVALIDARG, got %x\n", GetLastError());
844 SetLastError(0xdeadbeef);
845 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
846 ok(!ret && GetLastError() == E_INVALIDARG,
847 "Expected E_INVALIDARG, got %x\n", GetLastError());
848 /* The hash is still available. */
850 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
851 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
852 ok(size == sizeof(buf), "Unexpected size %d\n", size);
853 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
854 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
855 if (size == sizeof(buf))
856 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
857 /* After updating the hash, further updates aren't allowed on streamed
860 SetLastError(0xdeadbeef);
861 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
863 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
864 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
865 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */),
866 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
871 static const BYTE hashEmptyBareContent[] = {
872 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
873 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
874 static const BYTE hashEmptyContent[] = {
875 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
876 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
877 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
878 static const BYTE hashBareContent[] = {
879 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
880 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
881 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
882 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
883 static const BYTE hashContent[] = {
884 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
885 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
886 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
887 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
888 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
890 static const BYTE detachedHashNonFinalBareContent[] = {
891 0x30,0x20,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,0x00 };
894 static const BYTE detachedHashNonFinalContent[] = {
895 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
896 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
897 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
898 0x07,0x01,0x04,0x00 };
899 static const BYTE detachedHashBareContent[] = {
900 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
901 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
902 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
903 0x9d,0x2a,0x8f,0x26,0x2f };
904 static const BYTE detachedHashContent[] = {
905 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
906 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
907 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
908 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
909 0x9d,0x2a,0x8f,0x26,0x2f };
911 static void test_hash_msg_encoding(void)
914 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
916 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
917 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
919 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
920 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
922 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
923 hashEmptyBareContent, sizeof(hashEmptyBareContent));
924 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
925 hashEmptyContent, sizeof(hashEmptyContent));
926 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
927 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
928 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
929 hashBareContent, sizeof(hashBareContent));
930 check_param("hash content", msg, CMSG_CONTENT_PARAM,
931 hashContent, sizeof(hashContent));
933 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
934 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
935 CMSG_HASHED, &hashInfo, NULL, NULL);
936 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
937 hashEmptyBareContent, sizeof(hashEmptyBareContent));
938 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
939 hashEmptyContent, sizeof(hashEmptyContent));
940 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
941 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
942 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
943 hashBareContent, sizeof(hashBareContent));
944 check_param("hash content", msg, CMSG_CONTENT_PARAM,
945 hashContent, sizeof(hashContent));
947 /* Same test, but with CMSG_DETACHED_FLAG set */
948 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
949 CMSG_HASHED, &hashInfo, NULL, NULL);
950 check_param("detached hash empty bare content", msg,
951 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
952 sizeof(hashEmptyBareContent));
953 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
954 hashEmptyContent, sizeof(hashEmptyContent));
955 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
956 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
957 check_param("detached hash not final bare content", msg,
958 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
959 sizeof(detachedHashNonFinalBareContent));
960 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
961 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
962 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
963 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
964 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
965 detachedHashBareContent, sizeof(detachedHashBareContent));
966 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
967 detachedHashContent, sizeof(detachedHashContent));
968 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
969 detachedHashBareContent, sizeof(detachedHashBareContent));
970 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
971 detachedHashContent, sizeof(detachedHashContent));
973 /* In what appears to be a bug, streamed updates to hash messages don't
974 * call the output function.
976 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
978 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
979 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
980 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
981 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
983 check_updates("empty hash message", &empty_accum, &accum);
984 free_updates(&accum);
986 streamInfo.cbContent = sizeof(msgData);
987 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
989 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
990 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
992 check_updates("hash message", &empty_accum, &accum);
993 free_updates(&accum);
995 streamInfo.cbContent = sizeof(msgData);
996 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
997 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
998 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
999 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1001 check_updates("detached hash message", &empty_accum, &accum);
1002 free_updates(&accum);
1005 static void test_hash_msg(void)
1007 test_hash_msg_open();
1008 test_hash_msg_update();
1009 test_hash_msg_get_param();
1010 test_hash_msg_encoding();
1013 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1015 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1017 static BYTE serialNum[] = { 1 };
1018 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1019 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1021 static void test_signed_msg_open(void)
1025 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1026 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1027 CERT_INFO certInfo = { 0 };
1029 SetLastError(0xdeadbeef);
1030 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1032 ok(!msg && GetLastError() == E_INVALIDARG,
1033 "Expected E_INVALIDARG, got %x\n", GetLastError());
1034 signInfo.cbSize = sizeof(signInfo);
1035 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1037 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1040 signInfo.cSigners = 1;
1041 signInfo.rgSigners = &signer;
1042 /* With signer.pCertInfo unset, attempting to open this message this
1045 signer.pCertInfo = &certInfo;
1046 /* The cert info must contain a serial number and an issuer. */
1047 SetLastError(0xdeadbeef);
1048 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1050 /* NT: E_INVALIDARG, 9x: unchanged */
1051 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef),
1052 "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError());
1054 certInfo.SerialNumber.cbData = sizeof(serialNum);
1055 certInfo.SerialNumber.pbData = serialNum;
1056 SetLastError(0xdeadbeef);
1057 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1059 /* NT: E_INVALIDARG, 9x: unchanged */
1060 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef),
1061 "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError());
1063 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1064 certInfo.Issuer.pbData = encodedCommonName;
1065 SetLastError(0xdeadbeef);
1066 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1068 ok(!msg && GetLastError() == E_INVALIDARG,
1069 "Expected E_INVALIDARG, got %x\n", GetLastError());
1071 /* The signer's hCryptProv must be set to something. Whether it's usable
1072 * or not will be checked after the hash algorithm is checked (see next
1075 signer.hCryptProv = 1;
1076 SetLastError(0xdeadbeef);
1077 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1079 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1080 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1081 /* The signer's hash algorithm must also be set. */
1082 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1083 SetLastError(0xdeadbeef);
1084 /* Crashes in advapi32 in wine, don't do it */
1086 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1087 &signInfo, NULL, NULL);
1088 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1089 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1091 /* The signer's hCryptProv must also be valid. */
1092 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1093 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1094 if (!ret && GetLastError() == NTE_EXISTS) {
1095 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1098 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1101 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1103 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1107 CryptReleaseContext(signer.hCryptProv, 0);
1108 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1109 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1112 static const BYTE privKey[] = {
1113 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1114 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1115 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1116 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1117 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1118 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1119 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1120 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1121 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1122 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1123 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1124 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1125 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1126 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1127 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1128 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1129 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1130 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1131 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1132 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1133 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1134 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1135 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1136 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1137 static BYTE pubKey[] = {
1138 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1139 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1140 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1141 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1142 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1144 static void test_signed_msg_update(void)
1148 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1149 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1150 CERT_INFO certInfo = { 0 };
1153 certInfo.SerialNumber.cbData = sizeof(serialNum);
1154 certInfo.SerialNumber.pbData = serialNum;
1155 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1156 certInfo.Issuer.pbData = encodedCommonName;
1157 signer.pCertInfo = &certInfo;
1158 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1159 signInfo.cSigners = 1;
1160 signInfo.rgSigners = &signer;
1162 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1163 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1164 if (!ret && GetLastError() == NTE_EXISTS) {
1165 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1168 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1171 skip("No context for tests\n");
1175 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1176 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1177 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1178 /* Detached CMSG_SIGNED allows non-final updates. */
1179 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1180 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1181 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1182 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1183 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1184 /* The final update requires a private key in the hCryptProv, in order to
1185 * generate the signature.
1187 SetLastError(0xdeadbeef);
1188 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1189 ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1190 GetLastError() == NTE_NO_KEY),
1191 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1192 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1194 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1195 /* The final update should be able to succeed now that a key exists, but
1196 * the previous (invalid) final update prevents it.
1198 SetLastError(0xdeadbeef);
1199 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1200 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1201 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1204 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1205 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1206 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1207 /* Detached CMSG_SIGNED allows non-final updates. */
1208 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1209 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1210 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1211 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1212 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1213 /* Now that the private key exists, the final update can succeed (even
1216 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1217 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1218 /* But no updates are allowed after the final update. */
1219 SetLastError(0xdeadbeef);
1220 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1221 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1222 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1223 SetLastError(0xdeadbeef);
1224 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1225 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1226 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1229 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1231 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1232 /* Non-detached messages don't allow non-final updates.. */
1233 SetLastError(0xdeadbeef);
1234 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1235 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1236 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1237 /* but they do allow final ones. */
1238 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1239 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1241 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1243 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1244 /* They also allow final updates with no data. */
1245 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1246 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1249 CryptDestroyKey(key);
1250 CryptReleaseContext(signer.hCryptProv, 0);
1251 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1252 CRYPT_DELETEKEYSET);
1255 static const BYTE signedEmptyBareContent[] = {
1256 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1257 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1258 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1259 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1260 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1261 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1262 static const BYTE signedEmptyContent[] = {
1263 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1264 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1265 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1266 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1267 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1268 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1269 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1270 static const BYTE detachedSignedBareContent[] = {
1271 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1272 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1273 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1274 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1275 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1276 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1277 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1278 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1279 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1280 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1281 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1282 static const BYTE detachedSignedContent[] = {
1283 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1284 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1285 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1286 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1287 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1288 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1289 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1290 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1291 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1292 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1293 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1294 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1295 static const BYTE signedBareContent[] = {
1296 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1297 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1298 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1299 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1300 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1301 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1302 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1303 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1304 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1305 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1306 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1307 static const BYTE signedContent[] = {
1308 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1309 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1310 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1311 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1312 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1313 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1314 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1315 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1316 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1317 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1318 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1319 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1321 static const BYTE signedHash[] = {
1322 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1324 static const BYTE signedEncodedSigner[] = {
1325 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1326 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1327 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1328 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1329 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1330 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1331 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1332 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1333 static const BYTE signedWithAuthAttrsBareContent[] = {
1334 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1335 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1336 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1337 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1338 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1339 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1340 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1341 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1342 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1343 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1344 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1345 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1346 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1347 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1348 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1349 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1350 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1351 0xff,0xc6,0x33,0x63,0x34 };
1352 static BYTE cert[] = {
1353 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1354 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1355 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1356 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1357 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1358 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1359 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1360 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1361 0xff,0x02,0x01,0x01 };
1362 static BYTE v1CertWithPubKey[] = {
1363 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1364 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1365 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1366 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1367 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1368 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1369 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1370 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1371 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1372 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1374 static const BYTE signedWithCertEmptyBareContent[] = {
1375 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1376 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1377 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1378 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1379 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1380 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1381 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1382 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1383 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1384 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1385 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1386 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1387 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1388 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1389 static const BYTE signedWithCertBareContent[] = {
1390 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1391 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1392 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1393 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1394 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1395 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1396 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1397 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1398 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1399 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1400 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1401 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1402 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1403 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1404 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1405 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1406 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1407 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1408 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1409 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1410 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1411 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1412 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1413 0x30,0x30,0x30,0x30,0x5a };
1414 static const BYTE signedWithCrlEmptyBareContent[] = {
1415 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1416 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1417 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1418 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1419 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1420 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1421 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1422 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1423 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1424 static const BYTE signedWithCrlBareContent[] = {
1425 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1426 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1427 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1428 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1429 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1430 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1431 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1432 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1433 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1434 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1435 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1436 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1437 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1438 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1440 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1441 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1442 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1443 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1444 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1445 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1446 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1447 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1448 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1449 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1450 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1451 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1452 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1453 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1454 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1455 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1456 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1457 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1459 static const BYTE signedWithCertAndCrlBareContent[] = {
1460 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1461 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1462 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1463 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,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,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1466 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1467 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1468 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1469 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1470 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1471 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1472 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1473 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1474 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1475 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1476 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1477 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1478 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1479 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1480 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1481 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1482 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1483 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1484 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1485 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1486 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1487 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1488 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1489 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1490 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1491 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1492 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1493 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1494 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1495 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1496 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1497 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1498 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1499 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1500 static BYTE v1CertWithValidPubKey[] = {
1501 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1502 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1503 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1504 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1505 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1506 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1507 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1508 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1509 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1510 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1511 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1512 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1513 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1514 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1515 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1516 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1517 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1518 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1519 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1520 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1521 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1522 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1523 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1524 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1525 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1526 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1527 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1528 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1529 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1530 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1531 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1532 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1533 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1534 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1535 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1536 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1538 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1539 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1540 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1541 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1542 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1543 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1544 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1545 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1546 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1547 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1548 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1549 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1550 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1551 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1552 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1553 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1554 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1555 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1556 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1557 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1558 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1559 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1560 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1561 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1562 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1563 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1564 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1565 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1567 static void test_signed_msg_encoding(void)
1570 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1571 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1572 CERT_INFO certInfo = { 0 };
1573 CERT_BLOB encodedCert = { sizeof(cert), cert };
1574 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1575 char oid_common_name[] = szOID_COMMON_NAME;
1576 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1577 encodedCommonName };
1578 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1583 certInfo.SerialNumber.cbData = sizeof(serialNum);
1584 certInfo.SerialNumber.pbData = serialNum;
1585 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1586 certInfo.Issuer.pbData = encodedCommonName;
1587 signer.pCertInfo = &certInfo;
1588 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1589 signInfo.cSigners = 1;
1590 signInfo.rgSigners = &signer;
1592 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1593 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1594 if (!ret && GetLastError() == NTE_EXISTS) {
1595 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1598 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1601 skip("No context for tests\n");
1605 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1607 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1609 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1610 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1611 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1613 check_param("detached signed empty bare content", msg,
1614 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1615 sizeof(signedEmptyBareContent));
1616 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1617 signedEmptyContent, sizeof(signedEmptyContent));
1618 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1619 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1620 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1621 signedHash, sizeof(signedHash));
1622 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1623 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1624 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1625 detachedSignedContent, sizeof(detachedSignedContent));
1626 SetLastError(0xdeadbeef);
1627 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1628 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1629 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1630 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1631 signedEncodedSigner, sizeof(signedEncodedSigner));
1635 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1637 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1639 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1640 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1641 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1642 signedEmptyContent, sizeof(signedEmptyContent));
1643 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1644 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1645 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1646 signedBareContent, sizeof(signedBareContent));
1647 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1648 signedContent, sizeof(signedContent));
1652 signer.cAuthAttr = 1;
1653 signer.rgAuthAttr = &attr;
1654 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1656 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1658 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1659 check_param("signed with auth attrs bare content", msg,
1660 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1661 sizeof(signedWithAuthAttrsBareContent));
1665 signer.cAuthAttr = 0;
1666 signInfo.rgCertEncoded = &encodedCert;
1667 signInfo.cCertEncoded = 1;
1668 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1670 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1672 check_param("signed with cert empty bare content", msg,
1673 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1674 sizeof(signedWithCertEmptyBareContent));
1675 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1676 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1677 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1678 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1682 signInfo.cCertEncoded = 0;
1683 signInfo.rgCrlEncoded = &encodedCrl;
1684 signInfo.cCrlEncoded = 1;
1685 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1687 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1689 check_param("signed with crl empty bare content", msg,
1690 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1691 sizeof(signedWithCrlEmptyBareContent));
1692 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1693 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1694 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1695 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1699 signInfo.cCertEncoded = 1;
1700 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1702 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1704 check_param("signed with cert and crl empty bare content", msg,
1705 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1706 sizeof(signedWithCertAndCrlEmptyBareContent));
1707 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1708 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1709 check_param("signed with cert and crl bare content", msg,
1710 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1711 sizeof(signedWithCertAndCrlBareContent));
1715 /* Test with a cert with a (bogus) public key */
1716 signInfo.cCrlEncoded = 0;
1717 encodedCert.cbData = sizeof(v1CertWithPubKey);
1718 encodedCert.pbData = v1CertWithPubKey;
1719 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1721 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1722 check_param("signedWithCertWithPubKeyBareContent", msg,
1723 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1724 sizeof(signedWithCertWithPubKeyBareContent));
1727 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1728 encodedCert.pbData = v1CertWithValidPubKey;
1729 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1731 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1732 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1733 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1734 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1735 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1736 check_param("signedWithCertWithValidPubKeyContent", msg,
1737 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1738 sizeof(signedWithCertWithValidPubKeyContent));
1741 CryptDestroyKey(key);
1742 CryptReleaseContext(signer.hCryptProv, 0);
1743 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1744 CRYPT_DELETEKEYSET);
1747 static void test_signed_msg_get_param(void)
1751 DWORD size, value = 0;
1752 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1753 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1754 CERT_INFO certInfo = { 0 };
1756 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1758 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1760 /* Content and bare content are always gettable */
1762 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1763 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1765 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1766 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1767 /* For "signed" messages, so is the version. */
1769 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1770 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1771 size = sizeof(value);
1772 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1773 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1774 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1775 /* But for this message, with no signers, the hash and signer aren't
1779 SetLastError(0xdeadbeef);
1780 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1781 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1782 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1783 SetLastError(0xdeadbeef);
1784 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1785 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1786 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1787 /* As usual, the type isn't available. */
1788 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1789 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1790 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1794 certInfo.SerialNumber.cbData = sizeof(serialNum);
1795 certInfo.SerialNumber.pbData = serialNum;
1796 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1797 certInfo.Issuer.pbData = encodedCommonName;
1798 signer.pCertInfo = &certInfo;
1799 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1800 signInfo.cSigners = 1;
1801 signInfo.rgSigners = &signer;
1803 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1804 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1805 if (!ret && GetLastError() == NTE_EXISTS) {
1806 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1809 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1812 skip("No context for tests\n");
1816 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1818 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1820 /* This message, with one signer, has the hash and signer for index 0
1821 * available, but not for other indexes.
1824 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1825 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1826 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1827 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1829 SetLastError(0xdeadbeef);
1830 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1831 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1832 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1833 SetLastError(0xdeadbeef);
1834 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1835 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1836 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1837 /* As usual, the type isn't available. */
1838 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1839 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1840 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1844 CryptReleaseContext(signer.hCryptProv, 0);
1845 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1846 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1849 static void test_signed_msg(void)
1851 test_signed_msg_open();
1852 test_signed_msg_update();
1853 test_signed_msg_encoding();
1854 test_signed_msg_get_param();
1857 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1858 static const struct update_accum a4 = { 1, &b4 };
1860 static const BYTE bogusOIDContent[] = {
1861 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1863 static const BYTE bogusHashContent[] = {
1864 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1865 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1866 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1867 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1868 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1870 static void test_decode_msg_update(void)
1874 CMSG_STREAM_INFO streamInfo = { 0 };
1876 struct update_accum accum = { 0, NULL };
1878 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1879 /* Update with a full message in a final update */
1880 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1881 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1882 /* Can't update after a final update */
1883 SetLastError(0xdeadbeef);
1884 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1885 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1886 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1889 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1890 /* Can't send a non-final update without streaming */
1891 SetLastError(0xdeadbeef);
1892 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1894 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1895 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1896 /* A subsequent final update succeeds */
1897 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1898 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1901 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1902 /* Updating a message that has a NULL stream callback fails */
1903 SetLastError(0xdeadbeef);
1904 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1907 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1908 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1909 /* Changing the callback pointer after the fact yields the same error (so
1910 * the message must copy the stream info, not just store a pointer to it)
1912 streamInfo.pfnStreamOutput = nop_stream_output;
1913 SetLastError(0xdeadbeef);
1914 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1917 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1918 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1921 /* Empty non-final updates are allowed when streaming.. */
1922 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1923 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1924 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1925 /* but final updates aren't when not enough data has been received. */
1926 SetLastError(0xdeadbeef);
1927 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1929 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1930 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1933 /* Updating the message byte by byte is legal */
1934 streamInfo.pfnStreamOutput = accumulating_stream_output;
1935 streamInfo.pvArg = &accum;
1936 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1937 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1938 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1939 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1940 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1941 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1944 check_updates("byte-by-byte empty content", &a4, &accum);
1945 free_updates(&accum);
1947 /* Decoding bogus content fails in non-streaming mode.. */
1948 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1949 SetLastError(0xdeadbeef);
1950 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1951 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1952 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1954 /* and as the final update in streaming mode.. */
1955 streamInfo.pfnStreamOutput = nop_stream_output;
1956 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1957 SetLastError(0xdeadbeef);
1958 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1960 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1961 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1963 /* and even as a non-final update in streaming mode. */
1964 streamInfo.pfnStreamOutput = nop_stream_output;
1965 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1966 SetLastError(0xdeadbeef);
1967 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1969 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1970 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1973 /* An empty message can be opened with undetermined type.. */
1974 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1975 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1977 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1979 /* but decoding it as an explicitly typed message fails. */
1980 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1982 SetLastError(0xdeadbeef);
1983 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1985 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1986 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1988 /* On the other hand, decoding the bare content of an empty message fails
1989 * with unspecified type..
1991 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1992 SetLastError(0xdeadbeef);
1993 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1994 sizeof(dataEmptyBareContent), TRUE);
1995 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1996 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1998 /* but succeeds with explicit type. */
1999 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2001 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2002 sizeof(dataEmptyBareContent), TRUE);
2003 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2006 /* Decoding valid content with an unsupported OID fails */
2007 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2008 SetLastError(0xdeadbeef);
2009 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2010 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2011 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2014 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2015 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2016 SetLastError(0xdeadbeef);
2017 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2018 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2020 /* while with specified type it fails. */
2021 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2023 SetLastError(0xdeadbeef);
2024 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2025 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2026 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2028 /* On the other hand, decoding the bare content of an empty hash message
2029 * fails with unspecified type..
2031 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2032 SetLastError(0xdeadbeef);
2033 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2034 sizeof(hashEmptyBareContent), TRUE);
2035 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2036 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2038 /* but succeeds with explicit type. */
2039 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2041 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2042 sizeof(hashEmptyBareContent), TRUE);
2043 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2046 /* And again, opening a (non-empty) hash message with unspecified type
2049 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2050 SetLastError(0xdeadbeef);
2051 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2052 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2054 /* while with specified type it fails.. */
2055 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2057 SetLastError(0xdeadbeef);
2058 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2059 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2060 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2062 /* and decoding the bare content of a non-empty hash message fails with
2063 * unspecified type..
2065 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2066 SetLastError(0xdeadbeef);
2067 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2068 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2069 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2071 /* but succeeds with explicit type. */
2072 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2074 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2075 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2078 /* Opening a (non-empty) hash message with unspecified type and a bogus
2079 * hash value succeeds..
2081 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2082 SetLastError(0xdeadbeef);
2083 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2084 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2087 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2088 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2089 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2091 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2092 SetLastError(0xdeadbeef);
2093 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2094 sizeof(signedWithCertAndCrlBareContent), TRUE);
2095 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2096 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2098 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2100 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2101 sizeof(signedWithCertAndCrlBareContent), TRUE);
2102 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2105 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2107 /* The first update succeeds.. */
2108 ret = CryptMsgUpdate(msg, detachedSignedContent,
2109 sizeof(detachedSignedContent), TRUE);
2110 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2111 /* as does a second (probably to update the detached portion).. */
2112 ret = CryptMsgUpdate(msg, detachedSignedContent,
2113 sizeof(detachedSignedContent), TRUE);
2114 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2115 /* while a third fails. */
2116 ret = CryptMsgUpdate(msg, detachedSignedContent,
2117 sizeof(detachedSignedContent), TRUE);
2118 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2119 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2123 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2124 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2126 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2127 const CMSG_SIGNER_INFO *expected)
2129 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2130 expected->dwVersion, got->dwVersion);
2131 ok(got->Issuer.cbData == expected->Issuer.cbData,
2132 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2133 got->Issuer.cbData);
2134 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2135 "Unexpected issuer\n");
2136 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2137 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2138 got->SerialNumber.cbData);
2139 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2140 got->SerialNumber.cbData), "Unexpected serial number\n");
2141 /* FIXME: check more things */
2144 static const BYTE signedWithCertAndCrlComputedHash[] = {
2145 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2148 static void test_decode_msg_get_param(void)
2152 DWORD size = 0, value;
2155 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2156 SetLastError(0xdeadbeef);
2157 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2158 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2159 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2160 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2161 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2165 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2166 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2167 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2168 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2169 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2170 emptyHashParam, sizeof(emptyHashParam));
2172 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2173 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2174 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2176 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2178 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2179 hashParam, sizeof(hashParam));
2180 /* Curiously, getting the hash of index 1 succeeds, even though there's
2183 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2184 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2185 buf = CryptMemAlloc(size);
2188 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2189 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2190 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2193 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2194 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2195 value = CMSG_HASHED_DATA_V0;
2196 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2200 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2201 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2202 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2203 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2205 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2206 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2207 size = sizeof(value);
2209 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2210 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2211 ok(value == 1, "Expected 1 signer, got %d\n", value);
2213 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2214 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2216 buf = CryptMemAlloc(size);
2221 CMSG_SIGNER_INFO signer = { 0 };
2223 signer.dwVersion = 1;
2224 signer.Issuer.cbData = sizeof(encodedCommonName);
2225 signer.Issuer.pbData = encodedCommonName;
2226 signer.SerialNumber.cbData = sizeof(serialNum);
2227 signer.SerialNumber.pbData = serialNum;
2228 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2229 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2230 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2233 /* index is ignored when getting signer count */
2234 size = sizeof(value);
2235 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2236 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2237 ok(value == 1, "Expected 1 signer, got %d\n", value);
2238 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2239 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2240 ok(value == 0, "Expected 0 certs, got %d\n", value);
2241 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2242 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2243 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2245 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2247 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2248 sizeof(signedWithCertAndCrlBareContent), TRUE);
2249 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2250 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2251 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2252 ok(value == 1, "Expected 1 cert, got %d\n", value);
2253 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2254 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2255 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2256 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2257 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2258 check_param("signed with cert and CRL computed hash", msg,
2259 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2260 sizeof(signedWithCertAndCrlComputedHash));
2264 static void test_decode_msg(void)
2266 test_decode_msg_update();
2267 test_decode_msg_get_param();
2270 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2271 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2272 static BYTE encodedPubKey[] = {
2273 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2274 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2276 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2277 static BYTE mod_encoded[] = {
2278 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2281 static void test_msg_control(void)
2283 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2287 CERT_INFO certInfo = { 0 };
2288 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2289 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2290 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2293 ret = CryptMsgControl(NULL, 0, 0, NULL);
2296 /* Data encode messages don't allow any sort of control.. */
2297 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2299 /* either with no prior update.. */
2300 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2302 SetLastError(0xdeadbeef);
2303 ret = CryptMsgControl(msg, 0, i, NULL);
2304 ok(!ret && GetLastError() == E_INVALIDARG,
2305 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2307 /* or after an update. */
2308 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2310 SetLastError(0xdeadbeef);
2311 ret = CryptMsgControl(msg, 0, i, NULL);
2312 ok(!ret && GetLastError() == E_INVALIDARG,
2313 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2317 /* Hash encode messages don't allow any sort of control.. */
2318 hashInfo.cbSize = sizeof(hashInfo);
2319 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2320 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2322 /* either with no prior update.. */
2323 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2325 SetLastError(0xdeadbeef);
2326 ret = CryptMsgControl(msg, 0, i, NULL);
2327 ok(!ret && GetLastError() == E_INVALIDARG,
2328 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2330 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2331 /* or after an update. */
2332 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2334 SetLastError(0xdeadbeef);
2335 ret = CryptMsgControl(msg, 0, i, NULL);
2336 ok(!ret && GetLastError() == E_INVALIDARG,
2337 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2341 /* Signed encode messages likewise don't allow any sort of control.. */
2342 signInfo.cbSize = sizeof(signInfo);
2343 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2345 /* either before an update.. */
2346 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2348 SetLastError(0xdeadbeef);
2349 ret = CryptMsgControl(msg, 0, i, NULL);
2350 ok(!ret && GetLastError() == E_INVALIDARG,
2351 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2353 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2354 /* or after an update. */
2355 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2357 SetLastError(0xdeadbeef);
2358 ret = CryptMsgControl(msg, 0, i, NULL);
2359 ok(!ret && GetLastError() == E_INVALIDARG,
2360 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2364 /* Decode messages behave a bit differently. */
2365 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2366 /* Bad control type */
2367 SetLastError(0xdeadbeef);
2368 ret = CryptMsgControl(msg, 0, 0, NULL);
2369 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2370 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2371 SetLastError(0xdeadbeef);
2372 ret = CryptMsgControl(msg, 1, 0, NULL);
2373 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2374 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2375 /* Can't verify the hash of an indeterminate-type message */
2376 SetLastError(0xdeadbeef);
2377 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2378 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2379 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2381 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2383 /* Can't decrypt an indeterminate-type message */
2384 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2385 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2386 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2389 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2391 /* Can't verify the hash of an empty message */
2392 SetLastError(0xdeadbeef);
2393 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2395 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2396 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2398 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2400 /* Can't verify the signature of a hash message */
2401 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2402 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2403 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2404 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2406 /* Oddly enough, this fails */
2407 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2409 ok(!ret, "Expected failure\n");
2411 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2413 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2414 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2415 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2416 /* Can't decrypt an indeterminate-type message */
2417 SetLastError(0xdeadbeef);
2418 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2419 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2420 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2423 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2425 /* Can't verify the hash of a signed message */
2426 SetLastError(0xdeadbeef);
2427 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2428 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2429 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2430 /* Can't decrypt a signed message */
2431 SetLastError(0xdeadbeef);
2432 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2433 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2434 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2436 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2437 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2439 CryptMsgUpdate(msg, signedWithCertBareContent,
2440 sizeof(signedWithCertBareContent), TRUE);
2441 /* With an empty cert info, the signer can't be found in the message (and
2442 * the signature can't be verified.
2444 SetLastError(0xdeadbeef);
2445 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2446 ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2447 "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2448 /* The cert info is expected to have an issuer, serial number, and public
2451 certInfo.SerialNumber.cbData = sizeof(serialNum);
2452 certInfo.SerialNumber.pbData = serialNum;
2453 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2454 certInfo.Issuer.pbData = encodedCommonName;
2455 SetLastError(0xdeadbeef);
2456 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2457 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2458 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2460 /* This cert has a public key, but it's not in a usable form */
2461 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2463 CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2464 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2465 /* Again, cert info needs to have a public key set */
2466 SetLastError(0xdeadbeef);
2467 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2469 (GetLastError() == CRYPT_E_ASN1_EOD ||
2470 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2471 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2472 /* The public key is supposed to be in encoded form.. */
2473 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2474 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2475 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2476 SetLastError(0xdeadbeef);
2477 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2479 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2480 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2481 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2482 /* but not as a X509_PUBLIC_KEY_INFO.. */
2483 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2484 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2485 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2486 SetLastError(0xdeadbeef);
2487 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2489 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2490 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2491 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2492 /* This decodes successfully, but it doesn't match any key in the message */
2493 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2494 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2495 SetLastError(0xdeadbeef);
2496 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2497 /* In Wine's rsaenh, this fails to decode because the key length is too
2498 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
2503 (GetLastError() == NTE_BAD_SIGNATURE ||
2504 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2505 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2507 /* A message with no data doesn't have a valid signature */
2508 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2509 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2510 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2511 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2512 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2513 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2514 SetLastError(0xdeadbeef);
2515 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2517 (GetLastError() == NTE_BAD_SIGNATURE ||
2518 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2519 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2521 /* Finally, this succeeds */
2522 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2523 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2524 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2525 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2526 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2530 /* win9x has much less parameter checks and will crash on many tests
2531 * this code is from test_signed_msg_update()
2533 static BOOL detect_nt(void)
2536 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
2537 CERT_INFO certInfo = { 0 };
2540 certInfo.SerialNumber.cbData = sizeof(serialNum);
2541 certInfo.SerialNumber.pbData = serialNum;
2542 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2543 certInfo.Issuer.pbData = encodedCommonName;
2544 signer.pCertInfo = &certInfo;
2545 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2547 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2548 PROV_RSA_FULL, CRYPT_NEWKEYSET);
2549 if (!ret && GetLastError() == NTE_EXISTS) {
2550 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2554 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
2557 CryptReleaseContext(signer.hCryptProv, 0);
2558 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
2559 CRYPT_DELETEKEYSET);
2566 init_function_pointers();
2567 have_nt = detect_nt();
2569 /* Basic parameter checking tests */
2570 test_msg_open_to_encode();
2571 test_msg_open_to_decode();
2572 test_msg_get_param();
2576 /* Message-type specific tests */