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
26 #define CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS
27 #define CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS
30 #include "wine/test.h"
32 static BOOL have_nt = TRUE;
33 static BOOL old_crypt32 = FALSE;
34 static char oid_rsa_md5[] = szOID_RSA_MD5;
36 static BOOL (WINAPI * pCryptAcquireContextA)
37 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
38 static BOOL (WINAPI * pCryptAcquireContextW)
39 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
41 static void init_function_pointers(void)
43 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
45 #define GET_PROC(dll, func) \
46 p ## func = (void *)GetProcAddress(dll, #func); \
48 trace("GetProcAddress(%s) failed\n", #func);
50 GET_PROC(hAdvapi32, CryptAcquireContextA)
51 GET_PROC(hAdvapi32, CryptAcquireContextW)
56 static void test_msg_open_to_encode(void)
61 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
63 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
65 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
70 SetLastError(0xdeadbeef);
71 msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
72 ok(!msg && GetLastError() == E_INVALIDARG,
73 "Expected E_INVALIDARG, got %x\n", GetLastError());
74 SetLastError(0xdeadbeef);
75 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
76 ok(!msg && GetLastError() == E_INVALIDARG,
77 "Expected E_INVALIDARG, got %x\n", GetLastError());
79 /* Bad message types */
80 SetLastError(0xdeadbeef);
81 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
82 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
83 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
84 SetLastError(0xdeadbeef);
85 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
87 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
88 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
89 SetLastError(0xdeadbeef);
90 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
91 CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
92 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
93 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
94 SetLastError(0xdeadbeef);
95 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
97 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
98 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
101 static void test_msg_open_to_decode(void)
104 CMSG_STREAM_INFO streamInfo = { 0 };
106 SetLastError(0xdeadbeef);
107 msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
108 ok(!msg && GetLastError() == E_INVALIDARG,
109 "Expected E_INVALIDARG, got %x\n", GetLastError());
112 SetLastError(0xdeadbeef);
113 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
114 ok(!msg && GetLastError() == E_INVALIDARG,
115 "Expected E_INVALIDARG, got %x\n", GetLastError());
116 SetLastError(0xdeadbeef);
117 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
118 ok(!msg && GetLastError() == E_INVALIDARG,
119 "Expected E_INVALIDARG, got %x\n", GetLastError());
121 /* The message type can be explicit... */
122 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
124 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
126 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
128 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
130 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
132 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
134 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
136 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
138 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
139 CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
140 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
143 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
144 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
146 /* or even invalid. */
147 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
149 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
151 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
152 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
155 /* And even though the stream info parameter "must be set to NULL" for
156 * CMSG_HASHED, it's still accepted.
158 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
160 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
164 static void test_msg_get_param(void)
168 DWORD size, i, value;
169 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
170 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
173 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
174 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
175 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
178 /* Decoded messages */
179 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
180 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
181 /* For decoded messages, the type is always available */
183 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
184 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
185 size = sizeof(value);
186 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
187 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
188 /* For this (empty) message, the type isn't set */
189 ok(value == 0, "Expected type 0, got %d\n", value);
192 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
194 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
195 /* For explicitly typed messages, the type is known. */
196 size = sizeof(value);
197 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
198 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
199 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
200 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
203 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
204 ok(!ret, "Parameter %d: expected failure\n", i);
208 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
210 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
211 size = sizeof(value);
212 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
213 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
214 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
215 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
218 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
219 ok(!ret, "Parameter %d: expected failure\n", i);
223 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
225 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
226 size = sizeof(value);
227 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
228 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
229 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
230 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
233 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
234 ok(!ret, "Parameter %d: expected failure\n", i);
238 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
240 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
241 size = sizeof(value);
242 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
243 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
244 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
245 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
248 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
249 ok(!ret, "Parameter %d: expected failure\n", i);
253 /* Explicitly typed messages get their types set, even if they're invalid */
254 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
256 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
257 size = sizeof(value);
258 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
259 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
260 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
263 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
264 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
265 size = sizeof(value);
266 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
267 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
268 ok(value == 1000, "Expected 1000, got %d\n", value);
272 static void test_msg_close(void)
277 /* NULL succeeds.. */
278 ret = CryptMsgClose(NULL);
279 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
280 /* but an arbitrary pointer crashes. */
282 ret = CryptMsgClose((HCRYPTMSG)1);
283 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
285 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
286 ret = CryptMsgClose(msg);
287 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
290 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
291 const BYTE *expected, DWORD expectedSize)
298 ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
299 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */ ||
300 GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x, for some params */),
301 "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
304 win_skip("parameter %d not supported, skipping tests\n", param);
307 buf = HeapAlloc(GetProcessHeap(), 0, size);
308 ret = CryptMsgGetParam(msg, param, 0, buf, &size);
309 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
310 ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
312 if (size == expectedSize && size)
313 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
314 HeapFree(GetProcessHeap(), 0, buf);
317 static void test_data_msg_open(void)
320 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
321 CMSG_STREAM_INFO streamInfo = { 0 };
322 char oid[] = "1.2.3";
324 /* The data message type takes no additional info */
325 SetLastError(0xdeadbeef);
326 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
328 ok(!msg && GetLastError() == E_INVALIDARG,
329 "Expected E_INVALIDARG, got %x\n", GetLastError());
330 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
332 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
335 /* An empty stream info is allowed. */
336 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
338 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
341 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
342 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
344 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
346 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
347 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
348 CMSG_DATA, NULL, oid, NULL);
349 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
351 /* and when a stream info is given, even though you're not supposed to be
352 * able to use anything but szOID_RSA_data when streaming is being used.
354 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
355 CMSG_DATA, NULL, oid, &streamInfo);
356 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
360 static const BYTE msgData[] = { 1, 2, 3, 4 };
362 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
368 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
370 static void test_data_msg_update(void)
374 CMSG_STREAM_INFO streamInfo = { 0 };
376 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
378 /* Can't update a message that wasn't opened detached with final = FALSE */
379 SetLastError(0xdeadbeef);
380 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
381 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
382 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
383 /* Updating it with final = TRUE succeeds */
384 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
385 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
386 /* Any subsequent update will fail, as the last was final */
387 SetLastError(0xdeadbeef);
388 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
389 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
390 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
393 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
395 /* Starting with Vista, can update a message with no data. */
396 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
397 ok(ret || broken(!ret), "CryptMsgUpdate failed: %08x\n", GetLastError());
402 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
403 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
406 LPBYTE buf = CryptMemAlloc(size);
410 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, buf,
412 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
415 ok(size == sizeof(dataEmptyBareContent),
416 "unexpected size %d\n", size);
417 ok(!memcmp(buf, dataEmptyBareContent, size),
418 "unexpected value\n");
426 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
427 CMSG_DATA, NULL, NULL, NULL);
430 /* Doesn't appear to be able to update CMSG-DATA with non-final updates.
431 * On Win9x, this sometimes succeeds, sometimes fails with
432 * GetLastError() == 0, so it's not worth checking there.
434 SetLastError(0xdeadbeef);
435 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
437 (GetLastError() == E_INVALIDARG ||
438 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
439 "Expected E_INVALIDARG, got %x\n", GetLastError());
440 SetLastError(0xdeadbeef);
441 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
443 (GetLastError() == E_INVALIDARG ||
444 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
445 "Expected E_INVALIDARG, got %x\n", GetLastError());
448 skip("not updating CMSG_DATA with a non-final update\n");
449 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
450 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
455 /* Calling update after opening with an empty stream info (with a bogus
456 * output function) yields an error:
458 /* Crashes on some Win9x */
459 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
461 SetLastError(0xdeadbeef);
462 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
463 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
464 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
465 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
469 /* Calling update with a valid output function succeeds, even if the data
470 * exceeds the size specified in the stream info.
472 streamInfo.pfnStreamOutput = nop_stream_output;
473 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
475 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
476 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
477 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
478 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
482 static void test_data_msg_get_param(void)
487 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
489 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
492 /* Content and bare content are always gettable when not streaming */
494 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
495 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
497 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
498 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
499 /* But for this type of message, the signer and hash aren't applicable,
500 * and the type isn't available.
503 SetLastError(0xdeadbeef);
504 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
505 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
506 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
507 SetLastError(0xdeadbeef);
508 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
509 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
510 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
511 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
512 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
513 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
516 /* Can't get content or bare content when streaming */
517 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
519 SetLastError(0xdeadbeef);
520 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
521 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
522 "Expected E_INVALIDARG, got %x\n", GetLastError());
523 SetLastError(0xdeadbeef);
524 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
525 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
526 "Expected E_INVALIDARG, got %x\n", GetLastError());
530 static const BYTE dataEmptyContent[] = {
531 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
533 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
534 static const BYTE dataContent[] = {
535 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
536 0x04,0x04,0x01,0x02,0x03,0x04 };
541 CRYPT_DATA_BLOB *updates;
544 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
545 DWORD cb, BOOL final)
547 struct update_accum *accum = (struct update_accum *)pvArg;
551 accum->updates = CryptMemRealloc(accum->updates,
552 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
554 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
557 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
559 blob->pbData = CryptMemAlloc(cb);
562 memcpy(blob->pbData, pb, cb);
571 /* The updates of a (bogus) definite-length encoded message */
572 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
573 0x07,0x01,0xa0,0x02,0x04,0x00 };
574 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
575 static CRYPT_DATA_BLOB b1[] = {
580 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
581 /* The updates of a definite-length encoded message */
582 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
583 0x07,0x01,0xa0,0x06,0x04,0x04 };
584 static CRYPT_DATA_BLOB b2[] = {
588 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
589 /* The updates of an indefinite-length encoded message */
590 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
591 0x07,0x01,0xa0,0x80,0x24,0x80 };
592 static BYTE u5[] = { 0x04,0x04 };
593 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
594 static CRYPT_DATA_BLOB b3[] = {
602 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
604 static void check_updates(LPCSTR header, const struct update_accum *expected,
605 const struct update_accum *got)
609 ok(expected->cUpdates == got->cUpdates,
610 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
612 if (expected->cUpdates == got->cUpdates)
613 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
615 ok(expected->updates[i].cbData == got->updates[i].cbData,
616 "%s, update %d: expected %d bytes, got %d\n", header, i,
617 expected->updates[i].cbData, got->updates[i].cbData);
618 if (expected->updates[i].cbData && expected->updates[i].cbData ==
619 got->updates[i].cbData)
620 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
621 got->updates[i].cbData), "%s, update %d: unexpected value\n",
626 /* Frees the updates stored in accum */
627 static void free_updates(struct update_accum *accum)
631 for (i = 0; i < accum->cUpdates; i++)
632 CryptMemFree(accum->updates[i].pbData);
633 CryptMemFree(accum->updates);
634 accum->updates = NULL;
638 static void test_data_msg_encoding(void)
642 static char oid[] = "1.2.3";
643 struct update_accum accum = { 0, NULL };
644 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
646 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
648 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
649 dataEmptyBareContent, sizeof(dataEmptyBareContent));
650 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
651 sizeof(dataEmptyContent));
652 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
653 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
654 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
655 dataBareContent, sizeof(dataBareContent));
656 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
657 sizeof(dataContent));
659 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
660 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
661 CMSG_DATA, NULL, NULL, NULL);
662 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
663 dataEmptyBareContent, sizeof(dataEmptyBareContent));
664 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
665 sizeof(dataEmptyContent));
666 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
667 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
668 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
669 dataBareContent, sizeof(dataBareContent));
670 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
671 sizeof(dataContent));
673 /* The inner OID is apparently ignored */
674 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
676 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
677 dataEmptyBareContent, sizeof(dataEmptyBareContent));
678 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
679 dataEmptyContent, sizeof(dataEmptyContent));
680 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
681 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
682 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
683 dataBareContent, sizeof(dataBareContent));
684 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
685 sizeof(dataContent));
687 /* A streaming message is DER encoded if the length is not 0xffffffff, but
688 * curiously, updates aren't validated to make sure they don't exceed the
689 * stated length. (The resulting output will of course fail to decode.)
691 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
693 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
694 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
696 check_updates("bogus data message with definite length", &a1, &accum);
697 free_updates(&accum);
698 /* A valid definite-length encoding: */
699 streamInfo.cbContent = sizeof(msgData);
700 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
702 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
704 check_updates("data message with definite length", &a2, &accum);
705 free_updates(&accum);
706 /* An indefinite-length encoding: */
707 streamInfo.cbContent = 0xffffffff;
708 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
710 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
711 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
713 check_updates("data message with indefinite length", &a3, &accum);
714 free_updates(&accum);
717 static void test_data_msg(void)
719 test_data_msg_open();
720 test_data_msg_update();
721 test_data_msg_get_param();
722 test_data_msg_encoding();
725 static void test_hash_msg_open(void)
728 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
729 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
731 SetLastError(0xdeadbeef);
732 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
734 ok(!msg && GetLastError() == E_INVALIDARG,
735 "Expected E_INVALIDARG, got %x\n", GetLastError());
736 hashInfo.cbSize = sizeof(hashInfo);
737 SetLastError(0xdeadbeef);
738 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
740 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
741 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
742 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
743 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
745 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
747 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
748 CMSG_HASHED, &hashInfo, NULL, NULL);
749 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
751 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
752 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
753 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
757 static void test_hash_msg_update(void)
761 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
762 { oid_rsa_md5, { 0, NULL } }, NULL };
763 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
765 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
766 CMSG_HASHED, &hashInfo, NULL, NULL);
767 /* Detached hashed messages opened in non-streaming mode allow non-final
770 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
771 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
772 /* including non-final updates with no data.. */
773 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
774 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
775 /* and final updates with no data. */
776 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
777 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
778 /* But no updates are allowed after the final update. */
779 SetLastError(0xdeadbeef);
780 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
781 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
782 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
783 SetLastError(0xdeadbeef);
784 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
785 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
786 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
788 /* Non-detached messages, in contrast, don't allow non-final updates in
789 * non-streaming mode.
791 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
793 SetLastError(0xdeadbeef);
794 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
795 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
796 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
797 /* Final updates (including empty ones) are allowed. */
798 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
799 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
801 /* And, of course, streaming mode allows non-final updates */
802 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
804 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
805 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
807 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
808 * to be a bug, it isn't actually used - see encoding tests.)
810 streamInfo.pfnStreamOutput = NULL;
811 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
813 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
814 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
818 static const BYTE emptyHashParam[] = {
819 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
822 static void test_hash_msg_get_param(void)
826 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
827 { oid_rsa_md5, { 0, NULL } }, NULL };
829 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
832 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
834 /* Content and bare content are always gettable for non-streamed messages */
836 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
837 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
838 "CryptMsgGetParam failed: %08x\n", GetLastError());
840 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
841 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
842 "CryptMsgGetParam failed: %08x\n", GetLastError());
843 /* For an encoded hash message, the hash data aren't available */
844 SetLastError(0xdeadbeef);
845 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
846 ok(!ret && (GetLastError() == CRYPT_E_INVALID_MSG_TYPE ||
847 GetLastError() == OSS_LIMITED /* Win9x */),
848 "Expected CRYPT_E_INVALID_MSG_TYPE or OSS_LIMITED, got %08x\n",
850 /* The hash is also available. */
852 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
853 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
854 ok(size == sizeof(buf), "Unexpected size %d\n", size);
855 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
856 if (size == sizeof(buf))
857 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
858 /* By getting the hash, further updates are not allowed */
859 SetLastError(0xdeadbeef);
860 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
862 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
863 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
864 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
865 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
866 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
868 /* Even after a final update, the hash data aren't available */
869 SetLastError(0xdeadbeef);
870 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
871 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
872 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
873 /* The version is also available, and should be zero for this message. */
875 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
876 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
877 "CryptMsgGetParam failed: %08x\n", GetLastError());
878 size = sizeof(value);
879 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
880 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
881 "CryptMsgGetParam failed: %08x\n", GetLastError());
883 ok(value == 0, "Expected version 0, got %d\n", value);
884 /* As usual, the type isn't available. */
885 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
886 ok(!ret, "Expected failure\n");
889 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
891 /* Streamed messages don't allow you to get the content or bare content. */
892 SetLastError(0xdeadbeef);
893 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
894 ok(!ret && (GetLastError() == E_INVALIDARG ||
895 GetLastError() == OSS_LIMITED /* Win9x */),
896 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
897 SetLastError(0xdeadbeef);
898 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
899 ok(!ret && (GetLastError() == E_INVALIDARG ||
900 GetLastError() == OSS_LIMITED /* Win9x */),
901 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
902 /* The hash is still available. */
904 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
905 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
906 ok(size == sizeof(buf), "Unexpected size %d\n", size);
907 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
908 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
909 if (size == sizeof(buf))
910 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
911 /* After updating the hash, further updates aren't allowed on streamed
914 SetLastError(0xdeadbeef);
915 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
917 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
918 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
919 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
920 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
921 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
926 static const BYTE hashEmptyBareContent[] = {
927 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
928 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
929 static const BYTE hashEmptyContent[] = {
930 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
931 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
932 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
933 static const BYTE hashBareContent[] = {
934 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
935 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
936 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
937 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
938 static const BYTE hashContent[] = {
939 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
940 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
941 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
942 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
943 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
945 static const BYTE detachedHashNonFinalBareContent[] = {
946 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
947 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
948 0x07,0x01,0x04,0x00 };
949 static const BYTE detachedHashNonFinalContent[] = {
950 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
951 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
952 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
953 0x07,0x01,0x04,0x00 };
954 static const BYTE detachedHashBareContent[] = {
955 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
956 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
957 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
958 0x9d,0x2a,0x8f,0x26,0x2f };
959 static const BYTE detachedHashContent[] = {
960 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
961 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
962 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
963 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
964 0x9d,0x2a,0x8f,0x26,0x2f };
966 static void test_hash_msg_encoding(void)
969 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
971 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
972 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
974 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
975 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
977 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
978 hashEmptyBareContent, sizeof(hashEmptyBareContent));
979 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
980 hashEmptyContent, sizeof(hashEmptyContent));
981 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
982 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
983 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
984 hashBareContent, sizeof(hashBareContent));
985 check_param("hash content", msg, CMSG_CONTENT_PARAM,
986 hashContent, sizeof(hashContent));
988 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
989 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
990 CMSG_HASHED, &hashInfo, NULL, NULL);
991 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
992 hashEmptyBareContent, sizeof(hashEmptyBareContent));
993 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
994 hashEmptyContent, sizeof(hashEmptyContent));
995 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
996 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
997 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
998 hashBareContent, sizeof(hashBareContent));
999 check_param("hash content", msg, CMSG_CONTENT_PARAM,
1000 hashContent, sizeof(hashContent));
1002 /* Same test, but with CMSG_DETACHED_FLAG set */
1003 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
1004 CMSG_HASHED, &hashInfo, NULL, NULL);
1005 check_param("detached hash empty bare content", msg,
1006 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
1007 sizeof(hashEmptyBareContent));
1008 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
1009 hashEmptyContent, sizeof(hashEmptyContent));
1010 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1011 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1012 check_param("detached hash not final bare content", msg,
1013 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
1014 sizeof(detachedHashNonFinalBareContent));
1015 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
1016 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
1017 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1018 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1019 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1020 detachedHashBareContent, sizeof(detachedHashBareContent));
1021 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1022 detachedHashContent, sizeof(detachedHashContent));
1023 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1024 detachedHashBareContent, sizeof(detachedHashBareContent));
1025 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1026 detachedHashContent, sizeof(detachedHashContent));
1028 /* In what appears to be a bug, streamed updates to hash messages don't
1029 * call the output function.
1031 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
1033 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1034 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1035 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1036 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1038 check_updates("empty hash message", &empty_accum, &accum);
1039 free_updates(&accum);
1041 streamInfo.cbContent = sizeof(msgData);
1042 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
1044 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1045 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1047 check_updates("hash message", &empty_accum, &accum);
1048 free_updates(&accum);
1050 streamInfo.cbContent = sizeof(msgData);
1051 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
1052 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
1053 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1054 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1056 check_updates("detached hash message", &empty_accum, &accum);
1057 free_updates(&accum);
1060 static void test_hash_msg(void)
1062 test_hash_msg_open();
1063 test_hash_msg_update();
1064 test_hash_msg_get_param();
1065 test_hash_msg_encoding();
1068 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1070 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1072 static BYTE serialNum[] = { 1 };
1073 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1074 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1076 static void test_signed_msg_open(void)
1080 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1081 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1082 CERT_INFO certInfo = { 0 };
1084 SetLastError(0xdeadbeef);
1085 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1087 ok(!msg && GetLastError() == E_INVALIDARG,
1088 "Expected E_INVALIDARG, got %x\n", GetLastError());
1089 signInfo.cbSize = sizeof(signInfo);
1090 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1092 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1095 signInfo.cSigners = 1;
1096 signInfo.rgSigners = &signer;
1097 /* With signer.pCertInfo unset, attempting to open this message this
1100 signer.pCertInfo = &certInfo;
1101 /* The cert info must contain a serial number and an issuer. */
1102 SetLastError(0xdeadbeef);
1103 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1105 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1106 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1107 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1108 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1111 certInfo.SerialNumber.cbData = sizeof(serialNum);
1112 certInfo.SerialNumber.pbData = serialNum;
1113 SetLastError(0xdeadbeef);
1114 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1116 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1117 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1118 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1119 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1122 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1123 certInfo.Issuer.pbData = encodedCommonName;
1124 SetLastError(0xdeadbeef);
1125 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1127 ok(!msg && (GetLastError() == E_INVALIDARG ||
1128 GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1129 "Expected E_INVALIDARG or CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1131 /* The signer's hCryptProv must be set to something. Whether it's usable
1132 * or not will be checked after the hash algorithm is checked (see next
1135 signer.hCryptProv = 1;
1136 SetLastError(0xdeadbeef);
1137 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1139 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1140 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1141 /* The signer's hash algorithm must also be set. */
1142 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1143 SetLastError(0xdeadbeef);
1144 /* Crashes in advapi32 in wine, don't do it */
1146 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1147 &signInfo, NULL, NULL);
1148 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1149 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1151 /* The signer's hCryptProv must also be valid. */
1152 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1153 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1154 if (!ret && GetLastError() == NTE_EXISTS) {
1155 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1158 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1161 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1163 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1167 /* pCertInfo must still be set, but can be empty if the SignerId's issuer
1168 * and serial number are set.
1170 certInfo.Issuer.cbData = 0;
1171 certInfo.SerialNumber.cbData = 0;
1172 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1173 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1174 sizeof(encodedCommonName);
1175 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1176 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1178 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1179 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1181 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1184 CryptReleaseContext(signer.hCryptProv, 0);
1185 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1186 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1189 static const BYTE privKey[] = {
1190 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1191 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1192 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1193 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1194 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1195 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1196 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1197 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1198 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1199 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1200 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1201 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1202 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1203 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1204 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1205 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1206 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1207 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1208 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1209 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1210 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1211 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1212 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1213 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1214 static BYTE pubKey[] = {
1215 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1216 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1217 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1218 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1219 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1221 static void test_signed_msg_update(void)
1225 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1226 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1227 CERT_INFO certInfo = { 0 };
1230 certInfo.SerialNumber.cbData = sizeof(serialNum);
1231 certInfo.SerialNumber.pbData = serialNum;
1232 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1233 certInfo.Issuer.pbData = encodedCommonName;
1234 signer.pCertInfo = &certInfo;
1235 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1236 signInfo.cSigners = 1;
1237 signInfo.rgSigners = &signer;
1239 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1240 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1241 if (!ret && GetLastError() == NTE_EXISTS) {
1242 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1245 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1248 skip("No context for tests\n");
1252 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1253 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1254 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1255 /* Detached CMSG_SIGNED allows non-final updates. */
1256 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1257 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1258 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1259 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1260 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1261 /* The final update requires a private key in the hCryptProv, in order to
1262 * generate the signature.
1264 SetLastError(0xdeadbeef);
1265 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1267 (GetLastError() == NTE_BAD_KEYSET ||
1268 GetLastError() == NTE_NO_KEY ||
1269 broken(GetLastError() == ERROR_SUCCESS)), /* Some Win9x */
1270 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1271 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1273 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1274 /* The final update should be able to succeed now that a key exists, but
1275 * the previous (invalid) final update prevents it.
1277 SetLastError(0xdeadbeef);
1278 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1279 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1280 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1283 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1284 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1285 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1286 /* Detached CMSG_SIGNED allows non-final updates. */
1287 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1288 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1289 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1290 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1291 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1292 /* Now that the private key exists, the final update can succeed (even
1295 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1296 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1297 /* But no updates are allowed after the final update. */
1298 SetLastError(0xdeadbeef);
1299 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1300 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1301 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1302 SetLastError(0xdeadbeef);
1303 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1304 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1305 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1308 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1310 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1311 /* Non-detached messages don't allow non-final updates.. */
1312 SetLastError(0xdeadbeef);
1313 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1314 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1315 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1316 /* but they do allow final ones. */
1317 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1318 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1320 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1322 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1323 /* They also allow final updates with no data. */
1324 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1325 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1328 CryptDestroyKey(key);
1329 CryptReleaseContext(signer.hCryptProv, 0);
1330 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1331 CRYPT_DELETEKEYSET);
1334 static const BYTE signedEmptyBareContent[] = {
1335 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1336 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1337 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1338 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1339 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1340 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1341 static const BYTE signedEmptyContent[] = {
1342 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1343 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1344 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1345 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1346 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1347 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1348 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1349 static const BYTE detachedSignedBareContent[] = {
1350 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1351 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1352 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1353 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1354 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1355 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1356 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1357 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1358 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1359 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1360 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1361 static const BYTE detachedSignedContent[] = {
1362 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1363 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1364 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1365 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1366 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1367 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1368 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1369 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1370 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1371 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1372 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1373 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1374 static const BYTE signedBareContent[] = {
1375 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1376 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1377 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1378 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1379 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1380 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1381 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1382 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1383 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1384 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1385 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1386 static const BYTE signedContent[] = {
1387 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1388 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1389 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1390 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1391 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1392 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1393 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1394 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1395 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1396 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1397 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1398 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1400 static const BYTE signedHash[] = {
1401 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1403 static const BYTE signedKeyIdEmptyContent[] = {
1404 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
1405 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1406 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
1407 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1408 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1409 static const BYTE signedEncodedSigner[] = {
1410 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1411 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1412 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1413 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1414 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1415 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1416 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1417 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1418 static const BYTE signedWithAuthAttrsBareContent[] = {
1419 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1420 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1421 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1422 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1423 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1424 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1425 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1426 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1427 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1428 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1429 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1430 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1431 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1432 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1433 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1434 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1435 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1436 0xff,0xc6,0x33,0x63,0x34 };
1437 static BYTE cert[] = {
1438 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1439 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1440 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1441 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1442 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1443 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1444 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1445 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1446 0xff,0x02,0x01,0x01 };
1447 static BYTE v1CertWithPubKey[] = {
1448 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1449 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1450 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1451 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1452 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1453 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1454 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1455 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1456 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1457 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1459 static const BYTE signedWithCertEmptyBareContent[] = {
1460 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1461 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1462 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1463 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1464 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1465 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1466 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1467 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1468 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1469 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1470 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1471 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1472 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1473 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1474 static const BYTE signedWithCertBareContent[] = {
1475 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1476 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1477 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1478 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1479 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1480 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1481 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1482 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1483 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1484 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1485 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1486 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1487 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1488 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1489 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1490 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1491 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1492 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1493 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1494 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1495 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1496 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1497 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1498 0x30,0x30,0x30,0x30,0x5a };
1499 static const BYTE signedWithCrlEmptyBareContent[] = {
1500 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1501 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1502 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1503 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1504 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1505 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1506 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1507 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1508 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1509 static const BYTE signedWithCrlBareContent[] = {
1510 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1511 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1512 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1513 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1514 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1515 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1516 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1517 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1518 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1519 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1520 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1521 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1522 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1523 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1525 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1526 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1527 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1528 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1529 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1530 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1531 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1532 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1533 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1534 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1535 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1536 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1537 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1538 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1539 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1540 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1541 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1542 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1544 static const BYTE signedWithCertAndCrlBareContent[] = {
1545 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1546 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1547 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1548 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1549 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1550 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1551 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1552 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1553 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1554 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1555 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1556 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1557 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1558 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1559 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1560 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1561 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1562 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1563 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1564 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1565 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1566 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1567 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1568 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1569 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1570 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1571 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1572 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1573 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1574 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1575 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1576 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1577 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1578 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1579 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1580 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1581 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1582 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1583 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1584 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1585 static BYTE v1CertWithValidPubKey[] = {
1586 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1587 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1588 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1589 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1590 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1591 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1592 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1593 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1594 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1595 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1596 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1597 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1598 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1599 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1600 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1601 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1602 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1603 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1604 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1605 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1606 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1607 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1608 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1609 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1610 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1611 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1612 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1613 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1614 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1615 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1616 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1617 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1618 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1619 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1620 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1621 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1623 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1624 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1625 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1626 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1627 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1628 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1629 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1630 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1631 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1632 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1633 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1634 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1635 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1636 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1637 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1638 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1639 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1640 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1641 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1642 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1643 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1644 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1645 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1646 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1647 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1648 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1649 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1650 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1652 static void test_signed_msg_encoding(void)
1655 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1656 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1657 CERT_INFO certInfo = { 0 };
1658 CERT_BLOB encodedCert = { sizeof(cert), cert };
1659 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1660 char oid_common_name[] = szOID_COMMON_NAME;
1661 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1662 encodedCommonName };
1663 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1668 certInfo.SerialNumber.cbData = sizeof(serialNum);
1669 certInfo.SerialNumber.pbData = serialNum;
1670 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1671 certInfo.Issuer.pbData = encodedCommonName;
1672 signer.pCertInfo = &certInfo;
1673 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1674 signInfo.cSigners = 1;
1675 signInfo.rgSigners = &signer;
1677 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1678 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1679 if (!ret && GetLastError() == NTE_EXISTS) {
1680 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1683 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1686 skip("No context for tests\n");
1690 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1692 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1694 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1695 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1696 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1698 check_param("detached signed empty bare content", msg,
1699 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1700 sizeof(signedEmptyBareContent));
1701 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1702 signedEmptyContent, sizeof(signedEmptyContent));
1703 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1704 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1705 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1706 signedHash, sizeof(signedHash));
1707 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1708 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1709 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1710 detachedSignedContent, sizeof(detachedSignedContent));
1711 SetLastError(0xdeadbeef);
1712 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1713 ok(!ret && (GetLastError() == CRYPT_E_INVALID_INDEX ||
1714 broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */)),
1715 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1716 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1717 signedEncodedSigner, sizeof(signedEncodedSigner));
1721 certInfo.SerialNumber.cbData = 0;
1722 certInfo.Issuer.cbData = 0;
1723 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1724 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1725 U(signer.SignerId).KeyId.pbData = serialNum;
1726 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1728 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1729 check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM,
1730 signedKeyIdEmptyContent, sizeof(signedKeyIdEmptyContent));
1733 certInfo.SerialNumber.cbData = sizeof(serialNum);
1734 certInfo.SerialNumber.pbData = serialNum;
1735 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1736 certInfo.Issuer.pbData = encodedCommonName;
1737 signer.SignerId.dwIdChoice = 0;
1738 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1740 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1742 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1743 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1744 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1745 signedEmptyContent, sizeof(signedEmptyContent));
1746 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1747 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1748 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1749 signedBareContent, sizeof(signedBareContent));
1750 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1751 signedContent, sizeof(signedContent));
1755 signer.cAuthAttr = 1;
1756 signer.rgAuthAttr = &attr;
1757 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1759 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1761 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1762 check_param("signed with auth attrs bare content", msg,
1763 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1764 sizeof(signedWithAuthAttrsBareContent));
1768 signer.cAuthAttr = 0;
1769 signInfo.rgCertEncoded = &encodedCert;
1770 signInfo.cCertEncoded = 1;
1771 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1773 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1775 check_param("signed with cert empty bare content", msg,
1776 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1777 sizeof(signedWithCertEmptyBareContent));
1778 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1779 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1780 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1781 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1785 signInfo.cCertEncoded = 0;
1786 signInfo.rgCrlEncoded = &encodedCrl;
1787 signInfo.cCrlEncoded = 1;
1788 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1790 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1792 check_param("signed with crl empty bare content", msg,
1793 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1794 sizeof(signedWithCrlEmptyBareContent));
1795 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1796 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1797 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1798 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1802 signInfo.cCertEncoded = 1;
1803 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1805 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1807 check_param("signed with cert and crl empty bare content", msg,
1808 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1809 sizeof(signedWithCertAndCrlEmptyBareContent));
1810 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1811 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1812 check_param("signed with cert and crl bare content", msg,
1813 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1814 sizeof(signedWithCertAndCrlBareContent));
1818 /* Test with a cert with a (bogus) public key */
1819 signInfo.cCrlEncoded = 0;
1820 encodedCert.cbData = sizeof(v1CertWithPubKey);
1821 encodedCert.pbData = v1CertWithPubKey;
1822 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1824 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1825 check_param("signedWithCertWithPubKeyBareContent", msg,
1826 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1827 sizeof(signedWithCertWithPubKeyBareContent));
1830 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1831 encodedCert.pbData = v1CertWithValidPubKey;
1832 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1834 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1835 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1836 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1837 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1838 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1839 check_param("signedWithCertWithValidPubKeyContent", msg,
1840 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1841 sizeof(signedWithCertWithValidPubKeyContent));
1844 CryptDestroyKey(key);
1845 CryptReleaseContext(signer.hCryptProv, 0);
1846 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1847 CRYPT_DELETEKEYSET);
1850 static void test_signed_msg_get_param(void)
1854 DWORD size, value = 0;
1855 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1856 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1857 CERT_INFO certInfo = { 0 };
1859 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1861 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1863 /* Content and bare content are always gettable */
1865 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1866 ok(ret || broken(!ret /* Win9x */), "CryptMsgGetParam failed: %08x\n",
1870 skip("message parameters are broken, skipping tests\n");
1874 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1875 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1876 /* For "signed" messages, so is the version. */
1878 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1879 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1880 size = sizeof(value);
1881 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1882 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1883 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1884 /* But for this message, with no signers, the hash and signer aren't
1888 SetLastError(0xdeadbeef);
1889 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1890 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1891 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1892 SetLastError(0xdeadbeef);
1893 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1894 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1895 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1896 /* As usual, the type isn't available. */
1897 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1898 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1899 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1903 certInfo.SerialNumber.cbData = sizeof(serialNum);
1904 certInfo.SerialNumber.pbData = serialNum;
1905 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1906 certInfo.Issuer.pbData = encodedCommonName;
1907 signer.pCertInfo = &certInfo;
1908 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1909 signInfo.cSigners = 1;
1910 signInfo.rgSigners = &signer;
1912 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1913 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1914 if (!ret && GetLastError() == NTE_EXISTS) {
1915 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1918 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1921 skip("No context for tests\n");
1925 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1927 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1929 /* This message, with one signer, has the hash and signer for index 0
1930 * available, but not for other indexes.
1933 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1934 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1935 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1936 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1938 SetLastError(0xdeadbeef);
1939 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1940 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1941 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1942 SetLastError(0xdeadbeef);
1943 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1944 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1945 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1946 /* As usual, the type isn't available. */
1947 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1948 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1949 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1953 /* Opening the message using the CMS fields.. */
1954 certInfo.SerialNumber.cbData = 0;
1955 certInfo.Issuer.cbData = 0;
1956 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1957 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1958 sizeof(encodedCommonName);
1959 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1960 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1962 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1963 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1964 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1965 if (!ret && GetLastError() == NTE_EXISTS)
1966 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1968 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1969 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1970 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1971 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1972 /* still results in the version being 1 when the issuer and serial number
1973 * are used and no additional CMS fields are used.
1975 size = sizeof(value);
1976 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1977 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE),
1978 "CryptMsgGetParam failed: %08x\n", GetLastError());
1980 ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value);
1981 /* Apparently the encoded signer can be retrieved.. */
1982 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1983 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1984 /* but the signer info, CMS signer info, and cert ID can't be. */
1985 SetLastError(0xdeadbeef);
1986 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1987 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1988 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1989 SetLastError(0xdeadbeef);
1990 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1991 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1992 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1993 SetLastError(0xdeadbeef);
1994 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1995 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1996 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1999 /* Using the KeyId field of the SignerId results in the version becoming
2002 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2003 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
2004 U(signer.SignerId).KeyId.pbData = serialNum;
2005 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
2006 PROV_RSA_FULL, CRYPT_NEWKEYSET);
2007 if (!ret && GetLastError() == NTE_EXISTS)
2008 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
2010 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
2011 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
2012 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
2013 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
2014 size = sizeof(value);
2015 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
2016 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2018 ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value);
2019 /* Even for a CMS message, the signer can be retrieved.. */
2020 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
2021 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2022 /* but the signer info, CMS signer info, and cert ID can't be. */
2023 SetLastError(0xdeadbeef);
2024 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2025 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2026 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2027 SetLastError(0xdeadbeef);
2028 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2029 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2030 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2031 SetLastError(0xdeadbeef);
2032 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
2033 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2034 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2037 CryptReleaseContext(signer.hCryptProv, 0);
2038 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
2039 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2042 static void test_signed_msg(void)
2044 test_signed_msg_open();
2045 test_signed_msg_update();
2046 test_signed_msg_encoding();
2047 test_signed_msg_get_param();
2050 static char oid_rsa_rc4[] = szOID_RSA_RC4;
2052 static void test_enveloped_msg_open(void)
2056 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { 0 };
2057 PCCERT_CONTEXT context;
2059 SetLastError(0xdeadbeef);
2060 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2061 &envelopedInfo, NULL, NULL);
2062 ok(!msg && GetLastError() == E_INVALIDARG,
2063 "expected E_INVALIDARG, got %08x\n", GetLastError());
2065 envelopedInfo.cbSize = sizeof(envelopedInfo);
2066 SetLastError(0xdeadbeef);
2067 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2068 &envelopedInfo, NULL, NULL);
2070 (GetLastError() == CRYPT_E_UNKNOWN_ALGO ||
2071 GetLastError() == E_INVALIDARG), /* Win9x */
2072 "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", GetLastError());
2074 envelopedInfo.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4;
2075 SetLastError(0xdeadbeef);
2076 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2077 &envelopedInfo, NULL, NULL);
2079 broken(!msg), /* Win9x */
2080 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2083 envelopedInfo.cRecipients = 1;
2086 SetLastError(0xdeadbeef);
2087 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2088 &envelopedInfo, NULL, NULL);
2089 ok(!msg && GetLastError() == E_INVALIDARG,
2090 "expected E_INVALIDARG, got %08x\n", GetLastError());
2093 context = CertCreateCertificateContext(X509_ASN_ENCODING,
2094 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
2097 envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo;
2098 SetLastError(0xdeadbeef);
2099 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2100 &envelopedInfo, NULL, NULL);
2101 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2103 SetLastError(0xdeadbeef);
2104 ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL,
2105 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
2106 ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
2107 SetLastError(0xdeadbeef);
2108 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2109 &envelopedInfo, NULL, NULL);
2110 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2112 CryptReleaseContext(envelopedInfo.hCryptProv, 0);
2113 CertFreeCertificateContext(context);
2116 win_skip("failed to create certificate context, skipping tests\n");
2119 static void test_enveloped_msg_update(void)
2123 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2124 { oid_rsa_rc4, { 0, NULL } }, NULL };
2125 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
2127 SetLastError(0xdeadbeef);
2128 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2129 &envelopedInfo, NULL, NULL);
2131 broken(!msg), /* Win9x */
2132 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2135 SetLastError(0xdeadbeef);
2136 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2137 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2138 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2139 SetLastError(0xdeadbeef);
2140 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2141 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2142 SetLastError(0xdeadbeef);
2143 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2144 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2145 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2148 SetLastError(0xdeadbeef);
2149 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2150 &envelopedInfo, NULL, NULL);
2152 broken(!msg), /* Win9x */
2153 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2156 SetLastError(0xdeadbeef);
2157 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2158 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2159 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2160 SetLastError(0xdeadbeef);
2161 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2163 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2164 "CryptMsgUpdate failed: %08x\n", GetLastError());
2165 SetLastError(0xdeadbeef);
2166 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2167 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2168 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2171 SetLastError(0xdeadbeef);
2172 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2173 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2175 broken(!msg), /* Win9x */
2176 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2179 SetLastError(0xdeadbeef);
2180 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2181 ok(!ret && GetLastError() == E_INVALIDARG,
2182 "expected E_INVALIDARG, got %08x\n", GetLastError());
2183 SetLastError(0xdeadbeef);
2184 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2185 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2188 SetLastError(0xdeadbeef);
2189 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2190 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2192 broken(!msg), /* Win9x */
2193 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2196 SetLastError(0xdeadbeef);
2197 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2198 ok(!ret && GetLastError() == E_INVALIDARG,
2199 "expected E_INVALIDARG, got %08x\n", GetLastError());
2200 SetLastError(0xdeadbeef);
2201 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2203 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2204 "CryptMsgUpdate failed: %08x\n", GetLastError());
2207 SetLastError(0xdeadbeef);
2208 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2209 &envelopedInfo, NULL, &streamInfo);
2211 broken(!msg), /* Win9x */
2212 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2215 SetLastError(0xdeadbeef);
2216 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2217 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2218 SetLastError(0xdeadbeef);
2219 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2220 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2223 SetLastError(0xdeadbeef);
2224 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2225 &envelopedInfo, NULL, &streamInfo);
2227 broken(!msg), /* Win9x */
2228 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2231 SetLastError(0xdeadbeef);
2232 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2233 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2234 SetLastError(0xdeadbeef);
2235 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2237 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2238 "CryptMsgUpdate failed: %08x\n", GetLastError());
2243 static const BYTE envelopedEmptyBareContent[] = {
2244 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2245 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2246 0x03,0x04,0x05,0x00,0x80,0x00 };
2247 static const BYTE envelopedEmptyContent[] = {
2248 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24,
2249 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2250 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2251 0x03,0x04,0x05,0x00,0x80,0x00 };
2253 static void test_enveloped_msg_encoding(void)
2256 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2257 { oid_rsa_rc4, { 0, NULL } }, NULL };
2259 SetLastError(0xdeadbeef);
2260 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2261 &envelopedInfo, NULL, NULL);
2263 broken(!msg), /* Win9x */
2264 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2267 check_param("enveloped empty bare content", msg,
2268 CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent,
2269 sizeof(envelopedEmptyBareContent));
2270 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
2271 envelopedEmptyContent, sizeof(envelopedEmptyContent));
2276 static void test_enveloped_msg(void)
2278 test_enveloped_msg_open();
2279 test_enveloped_msg_update();
2280 test_enveloped_msg_encoding();
2283 static CRYPT_DATA_BLOB b4 = { 0, NULL };
2284 static const struct update_accum a4 = { 1, &b4 };
2286 static const BYTE bogusOIDContent[] = {
2287 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2289 static const BYTE bogusHashContent[] = {
2290 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2291 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2292 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2293 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2294 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2295 static const BYTE envelopedBareContentWithoutData[] = {
2296 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2297 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2298 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2299 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2300 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b,
2301 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f,
2302 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94,
2303 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72,
2304 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18,
2305 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3,
2306 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6,
2307 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49,
2308 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e,
2309 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2310 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 };
2312 static void test_decode_msg_update(void)
2316 CMSG_STREAM_INFO streamInfo = { 0 };
2318 struct update_accum accum = { 0, NULL };
2320 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2321 /* Update with a full message in a final update */
2322 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2323 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2324 /* Can't update after a final update */
2325 SetLastError(0xdeadbeef);
2326 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2327 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2328 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2331 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2332 /* Can't send a non-final update without streaming */
2333 SetLastError(0xdeadbeef);
2334 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2336 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2337 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2338 /* A subsequent final update succeeds */
2339 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2340 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2345 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2346 /* Updating a message that has a NULL stream callback fails */
2347 SetLastError(0xdeadbeef);
2348 /* Crashes on some Win9x */
2349 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2352 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2353 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2354 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2356 /* Changing the callback pointer after the fact yields the same error (so
2357 * the message must copy the stream info, not just store a pointer to it)
2359 streamInfo.pfnStreamOutput = nop_stream_output;
2360 SetLastError(0xdeadbeef);
2361 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2364 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2365 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2366 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2371 /* Empty non-final updates are allowed when streaming.. */
2372 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2373 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2374 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2375 /* but final updates aren't when not enough data has been received. */
2376 SetLastError(0xdeadbeef);
2377 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2379 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2380 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2383 /* Updating the message byte by byte is legal */
2384 streamInfo.pfnStreamOutput = accumulating_stream_output;
2385 streamInfo.pvArg = &accum;
2386 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2387 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2388 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2389 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2390 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2391 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2394 check_updates("byte-by-byte empty content", &a4, &accum);
2395 free_updates(&accum);
2397 /* Decoding bogus content fails in non-streaming mode.. */
2398 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2399 SetLastError(0xdeadbeef);
2400 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2401 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2402 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2403 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2406 /* and as the final update in streaming mode.. */
2407 streamInfo.pfnStreamOutput = nop_stream_output;
2408 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2409 SetLastError(0xdeadbeef);
2410 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2411 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2412 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2413 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2416 /* and even as a non-final update in streaming mode. */
2417 streamInfo.pfnStreamOutput = nop_stream_output;
2418 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2419 SetLastError(0xdeadbeef);
2420 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2422 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2423 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2424 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2428 /* An empty message can be opened with undetermined type.. */
2429 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2430 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2432 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2434 /* but decoding it as an explicitly typed message fails. */
2435 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2437 SetLastError(0xdeadbeef);
2438 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2440 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2441 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2442 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2445 /* On the other hand, decoding the bare content of an empty message fails
2446 * with unspecified type..
2448 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2449 SetLastError(0xdeadbeef);
2450 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2451 sizeof(dataEmptyBareContent), TRUE);
2452 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2453 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2454 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2457 /* but succeeds with explicit type. */
2458 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2460 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2461 sizeof(dataEmptyBareContent), TRUE);
2462 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2465 /* Decoding valid content with an unsupported OID fails */
2466 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2467 SetLastError(0xdeadbeef);
2468 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2469 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2470 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2473 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2474 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2475 SetLastError(0xdeadbeef);
2476 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2477 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2478 "CryptMsgUpdate failed: %08x\n", GetLastError());
2480 /* while with specified type it fails. */
2481 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2483 SetLastError(0xdeadbeef);
2484 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2485 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2486 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2487 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2488 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2491 /* On the other hand, decoding the bare content of an empty hash message
2492 * fails with unspecified type..
2494 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2495 SetLastError(0xdeadbeef);
2496 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2497 sizeof(hashEmptyBareContent), TRUE);
2498 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2499 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2500 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2501 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2504 /* but succeeds with explicit type. */
2505 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2507 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2508 sizeof(hashEmptyBareContent), TRUE);
2509 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2510 "CryptMsgUpdate failed: %x\n", GetLastError());
2513 /* And again, opening a (non-empty) hash message with unspecified type
2516 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2517 SetLastError(0xdeadbeef);
2518 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2519 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2521 /* while with specified type it fails.. */
2522 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2524 SetLastError(0xdeadbeef);
2525 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2526 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2527 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2528 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2529 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2532 /* and decoding the bare content of a non-empty hash message fails with
2533 * unspecified type..
2535 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2536 SetLastError(0xdeadbeef);
2537 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2538 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2539 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2540 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2541 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2544 /* but succeeds with explicit type. */
2545 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2547 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2548 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2551 /* Opening a (non-empty) hash message with unspecified type and a bogus
2552 * hash value succeeds..
2554 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2555 SetLastError(0xdeadbeef);
2556 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2557 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2560 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2561 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2562 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2564 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2565 SetLastError(0xdeadbeef);
2566 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2567 sizeof(signedWithCertAndCrlBareContent), TRUE);
2568 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2569 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2570 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2573 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2575 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2576 sizeof(signedWithCertAndCrlBareContent), TRUE);
2577 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2580 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2582 /* The first update succeeds.. */
2583 ret = CryptMsgUpdate(msg, detachedSignedContent,
2584 sizeof(detachedSignedContent), TRUE);
2585 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2586 /* as does a second (probably to update the detached portion).. */
2587 ret = CryptMsgUpdate(msg, detachedSignedContent,
2588 sizeof(detachedSignedContent), TRUE);
2589 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2590 /* while a third fails. */
2591 ret = CryptMsgUpdate(msg, detachedSignedContent,
2592 sizeof(detachedSignedContent), TRUE);
2593 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2594 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2597 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2598 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2599 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2600 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2601 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2602 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2603 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2604 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2605 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2607 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2608 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2609 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2612 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2614 SetLastError(0xdeadbeef);
2615 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2616 sizeof(envelopedEmptyBareContent), TRUE);
2617 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2620 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2622 SetLastError(0xdeadbeef);
2623 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2624 sizeof(envelopedEmptyContent), TRUE);
2626 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2627 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2628 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2631 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2632 SetLastError(0xdeadbeef);
2633 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2634 sizeof(envelopedEmptyBareContent), TRUE);
2636 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2637 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2638 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2641 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2642 SetLastError(0xdeadbeef);
2643 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2644 sizeof(envelopedEmptyContent), TRUE);
2645 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2648 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2650 SetLastError(0xdeadbeef);
2651 ret = CryptMsgUpdate(msg, envelopedBareContentWithoutData,
2652 sizeof(envelopedBareContentWithoutData), TRUE);
2653 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2657 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2658 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2660 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2661 const CMSG_SIGNER_INFO *expected)
2663 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2664 expected->dwVersion, got->dwVersion);
2665 ok(got->Issuer.cbData == expected->Issuer.cbData,
2666 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2667 got->Issuer.cbData);
2668 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2669 "Unexpected issuer\n");
2670 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2671 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2672 got->SerialNumber.cbData);
2673 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2674 got->SerialNumber.cbData), "Unexpected serial number\n");
2675 /* FIXME: check more things */
2678 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2679 const CMSG_CMS_SIGNER_INFO *expected)
2681 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2682 expected->dwVersion, got->dwVersion);
2683 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2684 "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2685 got->SignerId.dwIdChoice);
2686 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2688 if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2690 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2691 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2692 "Expected issuer size %d, got %d\n",
2693 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2694 U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2695 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2696 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2697 U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2698 "Unexpected issuer\n");
2699 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2700 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2701 "Expected serial number size %d, got %d\n",
2702 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2703 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2704 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2705 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2706 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2707 "Unexpected serial number\n");
2711 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2712 "expected key id size %d, got %d\n",
2713 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2714 ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2715 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2716 "unexpected key id\n");
2719 /* FIXME: check more things */
2722 static const BYTE signedWithCertAndCrlComputedHash[] = {
2723 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2725 static BYTE keyIdIssuer[] = {
2726 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2727 0x0a,0x07,0x01,0x04,0x01,0x01 };
2728 static const BYTE publicPrivateKeyPair[] = {
2729 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00,
2730 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b,
2731 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50,
2732 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54,
2733 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39,
2734 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7,
2735 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48,
2736 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17,
2737 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54,
2738 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33,
2739 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52,
2740 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e,
2741 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61,
2742 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb,
2743 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02,
2744 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90,
2745 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e,
2746 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce,
2747 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14,
2748 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5,
2749 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5,
2750 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94,
2751 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68,
2752 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71,
2753 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25,
2754 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc,
2755 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a,
2756 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64,
2757 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77,
2758 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68,
2759 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab,
2760 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9,
2761 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed,
2762 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01,
2763 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e,
2764 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71,
2765 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0,
2766 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87,
2767 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b,
2768 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e };
2769 static const BYTE envelopedMessage[] = {
2770 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,
2771 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,
2772 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,
2773 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,
2774 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
2775 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65,
2776 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae,
2777 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1,
2778 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51,
2779 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf,
2780 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b,
2781 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e,
2782 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e,
2783 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70,
2784 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,
2785 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,
2786 0x04,0x5f,0x80,0xf2,0x17 };
2787 static const BYTE envelopedBareMessage[] = {
2788 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2789 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2790 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2791 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2792 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d,
2793 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d,
2794 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5,
2795 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e,
2796 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2,
2797 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4,
2798 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70,
2799 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c,
2800 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55,
2801 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2802 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c,
2804 static const BYTE envelopedMessageWith3Recps[] = {
2805 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,
2806 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e,
2807 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,
2808 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,
2809 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,
2810 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e,
2811 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba,
2812 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f,
2813 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5,
2814 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21,
2815 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae,
2816 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0,
2817 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96,
2818 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae,
2819 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,
2820 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,
2821 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6,
2822 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
2823 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf,
2824 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9,
2825 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3,
2826 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02,
2827 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70,
2828 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3,
2829 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74,
2830 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94,
2831 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7,
2832 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,
2833 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,
2834 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
2835 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98,
2836 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5,
2837 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9,
2838 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3,
2839 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8,
2840 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac,
2841 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc,
2842 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5,
2843 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1,
2844 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
2845 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,
2846 0x80,0x04,0x4e,0x99,0x9d,0x4c };
2847 static const BYTE serialNumber[] = {
2848 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2,
2850 static const BYTE issuer[] = {
2851 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 };
2853 static void test_decode_msg_get_param(void)
2856 HCRYPTPROV hCryptProv;
2859 DWORD size = 0, value;
2861 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2863 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2864 SetLastError(0xdeadbeef);
2865 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2866 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2867 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2868 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2869 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2873 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2874 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2877 /* Crashes on some Win9x */
2878 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2879 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2880 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2881 emptyHashParam, sizeof(emptyHashParam));
2884 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2885 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2886 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2888 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2890 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2891 hashParam, sizeof(hashParam));
2892 /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2893 * even though there's only one hash.
2895 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2896 ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2897 "CryptMsgGetParam failed: %08x\n", GetLastError());
2899 buf = CryptMemAlloc(size);
2904 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2905 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2906 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2909 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2910 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2911 value = CMSG_HASHED_DATA_V0;
2912 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2916 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2917 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2918 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2919 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2921 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2922 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2923 size = sizeof(value);
2925 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2926 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2927 ok(value == 1, "Expected 1 signer, got %d\n", value);
2929 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2930 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2931 "CryptMsgGetParam failed: %08x\n", GetLastError());
2933 buf = CryptMemAlloc(size);
2938 CMSG_SIGNER_INFO signer = { 0 };
2940 signer.dwVersion = 1;
2941 signer.Issuer.cbData = sizeof(encodedCommonName);
2942 signer.Issuer.pbData = encodedCommonName;
2943 signer.SerialNumber.cbData = sizeof(serialNum);
2944 signer.SerialNumber.pbData = serialNum;
2945 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2946 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2947 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2950 /* Getting the CMS signer info of a PKCS7 message is possible. */
2952 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2953 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2954 "CryptMsgGetParam failed: %08x\n", GetLastError());
2956 buf = CryptMemAlloc(size);
2961 CMSG_CMS_SIGNER_INFO signer = { 0 };
2963 signer.dwVersion = 1;
2964 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2965 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2966 sizeof(encodedCommonName);
2967 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2968 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2970 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2971 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2972 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2973 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2976 /* index is ignored when getting signer count */
2977 size = sizeof(value);
2978 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2979 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2980 ok(value == 1, "Expected 1 signer, got %d\n", value);
2981 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2982 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2983 ok(value == 0, "Expected 0 certs, got %d\n", value);
2984 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2985 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2986 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2988 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2990 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2991 sizeof(signedWithCertAndCrlBareContent), TRUE);
2992 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2993 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2994 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2995 ok(value == 1, "Expected 1 cert, got %d\n", value);
2996 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2997 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2998 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2999 ok(value == 1, "Expected 1 CRL, got %d\n", value);
3000 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
3001 check_param("signed with cert and CRL computed hash", msg,
3002 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
3003 sizeof(signedWithCertAndCrlComputedHash));
3006 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3007 ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
3008 sizeof(signedKeyIdEmptyContent), TRUE);
3009 if (!ret && GetLastError() == OSS_DATA_ERROR)
3012 win_skip("Subsequent tests crash on some Win9x\n");
3015 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3016 size = sizeof(value);
3017 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
3018 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3019 ok(value == 1, "Expected 1 signer, got %d\n", value);
3020 /* Getting the regular (non-CMS) signer info from a CMS message is also
3024 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
3025 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3027 buf = CryptMemAlloc(size);
3032 CMSG_SIGNER_INFO signer;
3035 /* and here's the little oddity: for a CMS message using the key id
3036 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
3037 * a signer with a zero (not empty) serial number, and whose issuer is
3038 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
3039 * and value of the key id.
3041 signer.dwVersion = CMSG_SIGNED_DATA_V3;
3042 signer.Issuer.cbData = sizeof(keyIdIssuer);
3043 signer.Issuer.pbData = keyIdIssuer;
3044 signer.SerialNumber.cbData = 1;
3045 signer.SerialNumber.pbData = &zero;
3046 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
3047 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
3051 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
3052 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3054 buf = CryptMemAlloc(size);
3059 CMSG_CMS_SIGNER_INFO signer = { 0 };
3061 signer.dwVersion = CMSG_SIGNED_DATA_V3;
3062 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
3063 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
3064 U(signer.SignerId).KeyId.pbData = serialNum;
3065 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3066 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
3067 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
3072 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3074 CryptMsgUpdate(msg, envelopedEmptyBareContent,
3075 sizeof(envelopedEmptyBareContent), TRUE);
3076 check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL,
3080 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3081 CryptMsgUpdate(msg, envelopedEmptyContent, sizeof(envelopedEmptyContent),
3083 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0);
3086 pCryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL,
3087 CRYPT_VERIFYCONTEXT);
3088 SetLastError(0xdeadbeef);
3089 ret = CryptImportKey(hCryptProv, publicPrivateKeyPair,
3090 sizeof(publicPrivateKeyPair), 0, 0, &key);
3092 broken(!ret && GetLastError() == NTE_PERM), /* WinME and some NT4 */
3093 "CryptImportKey failed: %08x\n", GetLastError());
3095 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3096 CryptMsgUpdate(msg, envelopedMessage, sizeof(envelopedMessage), TRUE);
3097 check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM,
3098 envelopedMessage + sizeof(envelopedMessage) - 4, 4);
3101 decryptPara.hCryptProv = hCryptProv;
3102 SetLastError(0xdeadbeef);
3103 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3104 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3105 decryptPara.hCryptProv = 0;
3106 SetLastError(0xdeadbeef);
3107 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3108 ok(!ret && GetLastError() == CRYPT_E_ALREADY_DECRYPTED,
3109 "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError());
3110 check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData,
3114 win_skip("failed to import a key, skipping tests\n");
3117 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3119 CryptMsgUpdate(msg, envelopedBareMessage, sizeof(envelopedBareMessage),
3121 check_param("enveloped bare message before decrypting", msg,
3122 CMSG_CONTENT_PARAM, envelopedBareMessage +
3123 sizeof(envelopedBareMessage) - 4, 4);
3126 decryptPara.hCryptProv = hCryptProv;
3127 SetLastError(0xdeadbeef);
3128 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3129 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3130 check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData,
3134 win_skip("failed to import a key, skipping tests\n");
3138 CryptDestroyKey(key);
3139 CryptReleaseContext(hCryptProv, 0);
3141 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3142 CryptMsgUpdate(msg, envelopedMessageWith3Recps,
3143 sizeof(envelopedMessageWith3Recps), TRUE);
3145 check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM,
3146 (const BYTE *)&value, sizeof(value));
3148 SetLastError(0xdeadbeef);
3149 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 3, NULL, &size);
3150 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3151 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3153 SetLastError(0xdeadbeef);
3154 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, NULL, &size);
3155 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3156 ok(size >= 142, "unexpected size: %u\n", size);
3158 buf = CryptMemAlloc(size);
3163 CERT_INFO *certInfo = (CERT_INFO *)buf;
3165 SetLastError(0xdeadbeef);
3166 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, buf, &size);
3167 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3168 ok(certInfo->SerialNumber.cbData == sizeof(serialNumber),
3169 "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData);
3170 ok(!memcmp(certInfo->SerialNumber.pbData, serialNumber,
3171 sizeof(serialNumber)), "unexpected serial number\n");
3172 ok(certInfo->Issuer.cbData == sizeof(issuer),
3173 "unexpected issuer size: %u\n", certInfo->Issuer.cbData);
3174 ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)),
3175 "unexpected issuer\n");
3181 static void test_decode_msg(void)
3183 test_decode_msg_update();
3184 test_decode_msg_get_param();
3187 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
3188 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
3189 static BYTE encodedPubKey[] = {
3190 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
3191 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
3193 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
3194 static BYTE mod_encoded[] = {
3195 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
3198 static void test_msg_control(void)
3200 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3204 CERT_INFO certInfo = { 0 };
3205 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
3206 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
3207 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
3210 ret = CryptMsgControl(NULL, 0, 0, NULL);
3213 /* Data encode messages don't allow any sort of control.. */
3214 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
3216 /* either with no prior update.. */
3217 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3219 SetLastError(0xdeadbeef);
3220 ret = CryptMsgControl(msg, 0, i, NULL);
3221 ok(!ret && GetLastError() == E_INVALIDARG,
3222 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3224 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3225 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3226 /* or after an update. */
3227 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3229 SetLastError(0xdeadbeef);
3230 ret = CryptMsgControl(msg, 0, i, NULL);
3231 ok(!ret && GetLastError() == E_INVALIDARG,
3232 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3236 /* Hash encode messages don't allow any sort of control.. */
3237 hashInfo.cbSize = sizeof(hashInfo);
3238 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
3239 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
3241 /* either with no prior update.. */
3242 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3244 SetLastError(0xdeadbeef);
3245 ret = CryptMsgControl(msg, 0, i, NULL);
3246 ok(!ret && GetLastError() == E_INVALIDARG,
3247 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3249 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3250 /* or after an update. */
3251 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3253 SetLastError(0xdeadbeef);
3254 ret = CryptMsgControl(msg, 0, i, NULL);
3255 ok(!ret && GetLastError() == E_INVALIDARG,
3256 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3260 /* Signed encode messages likewise don't allow any sort of control.. */
3261 signInfo.cbSize = sizeof(signInfo);
3262 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
3264 /* either before an update.. */
3265 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3267 SetLastError(0xdeadbeef);
3268 ret = CryptMsgControl(msg, 0, i, NULL);
3269 ok(!ret && GetLastError() == E_INVALIDARG,
3270 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3272 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3273 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3274 /* or after an update. */
3275 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3277 SetLastError(0xdeadbeef);
3278 ret = CryptMsgControl(msg, 0, i, NULL);
3279 ok(!ret && GetLastError() == E_INVALIDARG,
3280 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3284 /* Decode messages behave a bit differently. */
3285 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3286 /* Bad control type */
3287 SetLastError(0xdeadbeef);
3288 ret = CryptMsgControl(msg, 0, 0, NULL);
3289 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3290 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3291 SetLastError(0xdeadbeef);
3292 ret = CryptMsgControl(msg, 1, 0, NULL);
3293 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3294 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3295 /* Can't verify the hash of an indeterminate-type message */
3296 SetLastError(0xdeadbeef);
3297 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3298 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3299 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3301 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
3303 /* Can't decrypt an indeterminate-type message */
3304 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3305 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3306 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3311 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3313 /* Can't verify the hash of an empty message */
3314 SetLastError(0xdeadbeef);
3315 /* Crashes on some Win9x */
3316 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3318 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3319 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3321 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3323 /* Can't verify the signature of a hash message */
3324 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3325 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3326 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3327 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
3329 /* Oddly enough, this fails, crashes on some Win9x */
3330 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3331 ok(!ret, "Expected failure\n");
3334 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3336 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
3337 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3338 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3339 /* Can't decrypt an indeterminate-type message */
3340 SetLastError(0xdeadbeef);
3341 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3342 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3343 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3346 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3348 /* Can't verify the hash of a detached message before it's been updated. */
3349 SetLastError(0xdeadbeef);
3350 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3351 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3352 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3353 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3355 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3356 /* Still can't verify the hash of a detached message with the content
3357 * of the detached hash given..
3359 SetLastError(0xdeadbeef);
3360 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3361 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
3362 "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
3363 /* and giving the content of the message after attempting to verify the
3366 SetLastError(0xdeadbeef);
3367 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3370 (GetLastError() == NTE_BAD_HASH_STATE ||
3371 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3372 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
3373 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3374 "got %08x\n", GetLastError());
3377 /* Finally, verifying the hash of a detached message in the correct order:
3378 * 1. Update with the detached hash message
3379 * 2. Update with the content of the message
3380 * 3. Verifying the hash of the message
3383 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3385 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3387 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3388 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3389 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3390 SetLastError(0xdeadbeef);
3391 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3392 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3395 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3397 /* Can't verify the hash of a signed message */
3398 SetLastError(0xdeadbeef);
3399 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3400 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3401 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3402 /* Can't decrypt a signed message */
3403 SetLastError(0xdeadbeef);
3404 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3405 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3406 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3408 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3409 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3411 CryptMsgUpdate(msg, signedWithCertBareContent,
3412 sizeof(signedWithCertBareContent), TRUE);
3413 /* With an empty cert info, the signer can't be found in the message (and
3414 * the signature can't be verified.
3416 SetLastError(0xdeadbeef);
3417 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3418 ok(!ret && (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND ||
3419 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3420 "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n",
3422 /* The cert info is expected to have an issuer, serial number, and public
3425 certInfo.SerialNumber.cbData = sizeof(serialNum);
3426 certInfo.SerialNumber.pbData = serialNum;
3427 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3428 certInfo.Issuer.pbData = encodedCommonName;
3429 SetLastError(0xdeadbeef);
3430 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3431 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3432 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3433 "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError());
3435 /* This cert has a public key, but it's not in a usable form */
3436 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3438 ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
3439 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
3442 /* Crashes on some Win9x */
3443 /* Again, cert info needs to have a public key set */
3444 SetLastError(0xdeadbeef);
3445 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3447 (GetLastError() == CRYPT_E_ASN1_EOD ||
3448 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3449 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3450 /* The public key is supposed to be in encoded form.. */
3451 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3452 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3453 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
3454 SetLastError(0xdeadbeef);
3455 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3457 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3458 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3459 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3460 /* but not as a X509_PUBLIC_KEY_INFO.. */
3461 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3462 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
3463 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
3464 SetLastError(0xdeadbeef);
3465 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3467 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3468 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3469 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3470 /* This decodes successfully, but it doesn't match any key in the message */
3471 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
3472 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
3473 SetLastError(0xdeadbeef);
3474 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3475 /* In Wine's rsaenh, this fails to decode because the key length is too
3476 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
3481 (GetLastError() == NTE_BAD_SIGNATURE ||
3482 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3483 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3486 /* A message with no data doesn't have a valid signature */
3487 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3488 ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
3489 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
3492 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3493 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
3494 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
3495 SetLastError(0xdeadbeef);
3496 /* Crashes on some Win9x */
3497 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3499 (GetLastError() == NTE_BAD_SIGNATURE ||
3500 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3501 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3504 /* Finally, this succeeds */
3505 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3506 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3507 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3508 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3509 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3510 "CryptMsgControl failed: %08x\n", GetLastError());
3513 /* Test verifying signature of a detached signed message */
3514 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3516 ret = CryptMsgUpdate(msg, detachedSignedContent,
3517 sizeof(detachedSignedContent), TRUE);
3518 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3519 /* Can't verify the sig without having updated the data */
3520 SetLastError(0xdeadbeef);
3521 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3522 ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
3523 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3524 "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n",
3526 /* Now that the signature's been checked, can't do the final update */
3527 SetLastError(0xdeadbeef);
3528 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3531 (GetLastError() == NTE_BAD_HASH_STATE ||
3532 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3533 GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */
3534 broken(ret), /* Win9x */
3535 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3536 "got %08x\n", GetLastError());
3538 /* Updating with the detached portion of the message and the data of the
3539 * the message allows the sig to be verified.
3541 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3543 ret = CryptMsgUpdate(msg, detachedSignedContent,
3544 sizeof(detachedSignedContent), TRUE);
3545 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3546 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3547 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3548 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3549 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3550 "CryptMsgControl failed: %08x\n", GetLastError());
3553 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3555 decryptPara.cbSize = 0;
3556 SetLastError(0xdeadbeef);
3557 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3558 ok(!ret && GetLastError() == E_INVALIDARG,
3559 "expected E_INVALIDARG, got %08x\n", GetLastError());
3560 decryptPara.cbSize = sizeof(decryptPara);
3563 SetLastError(0xdeadbeef);
3564 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3565 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3566 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3568 SetLastError(0xdeadbeef);
3569 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
3570 sizeof(envelopedEmptyBareContent), TRUE);
3571 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3572 SetLastError(0xdeadbeef);
3573 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3574 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3575 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3578 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3580 SetLastError(0xdeadbeef);
3581 ret = CryptMsgUpdate(msg, envelopedBareMessage,
3582 sizeof(envelopedBareMessage), TRUE);
3583 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3584 SetLastError(0xdeadbeef);
3585 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3586 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
3587 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
3591 /* win9x has much less parameter checks and will crash on many tests
3592 * this code is from test_signed_msg_update()
3594 static BOOL detect_nt(void)
3597 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
3598 CERT_INFO certInfo = { 0 };
3600 if (!pCryptAcquireContextW)
3603 certInfo.SerialNumber.cbData = sizeof(serialNum);
3604 certInfo.SerialNumber.pbData = serialNum;
3605 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3606 certInfo.Issuer.pbData = encodedCommonName;
3607 signer.pCertInfo = &certInfo;
3608 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3610 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3611 PROV_RSA_FULL, CRYPT_NEWKEYSET);
3612 if (!ret && GetLastError() == NTE_EXISTS) {
3613 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3617 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
3620 CryptReleaseContext(signer.hCryptProv, 0);
3621 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
3622 CRYPT_DELETEKEYSET);
3627 static void test_msg_get_and_verify_signer(void)
3631 PCCERT_CONTEXT signer;
3638 CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
3639 CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3642 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3643 /* An empty message has no signer */
3644 SetLastError(0xdeadbeef);
3645 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3646 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3647 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3648 /* The signer is cleared on error */
3649 signer = (PCCERT_CONTEXT)0xdeadbeef;
3650 SetLastError(0xdeadbeef);
3651 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3652 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3653 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3654 ok(!signer, "expected signer to be NULL\n");
3655 /* The signer index is also cleared on error */
3656 signerIndex = 0xdeadbeef;
3657 SetLastError(0xdeadbeef);
3658 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3659 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3660 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3661 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
3662 /* An unsigned message (msgData isn't a signed message at all)
3663 * likewise has no signer.
3665 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3666 SetLastError(0xdeadbeef);
3667 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3668 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3669 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3672 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3673 /* A "signed" message created with no signer cert likewise has no signer */
3674 ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
3677 /* Crashes on most Win9x */
3678 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3679 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3680 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3684 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3685 /* A signed message succeeds, .. */
3686 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3687 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3688 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3689 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3690 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3691 /* the signer index can be retrieved, .. */
3692 signerIndex = 0xdeadbeef;
3693 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3694 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3695 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3697 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
3698 /* as can the signer cert. */
3699 signer = (PCCERT_CONTEXT)0xdeadbeef;
3700 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3701 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3702 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3704 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3705 "expected a valid signer\n");
3706 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3707 CertFreeCertificateContext(signer);
3708 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3710 signerIndex = 0xdeadbeef;
3711 SetLastError(0xdeadbeef);
3712 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3713 NULL, &signerIndex);
3714 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3715 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3716 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3717 * message signer not to be found.
3719 SetLastError(0xdeadbeef);
3720 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3722 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3723 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3724 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3725 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3726 * the message signer not to be found.
3728 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3729 CERT_STORE_CREATE_NEW_FLAG, NULL);
3730 SetLastError(0xdeadbeef);
3731 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3733 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3734 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3735 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3736 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3737 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3738 CERT_STORE_ADD_ALWAYS, NULL);
3739 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win98 */),
3740 "CertAddEncodedCertificateToStore failed: 0x%08x\n", GetLastError());
3741 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3742 * the signer succeeds.
3744 SetLastError(0xdeadbeef);
3745 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3747 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3748 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3749 CertCloseStore(store, 0);
3755 init_function_pointers();
3756 have_nt = detect_nt();
3758 win_skip("Win9x crashes on some parameter checks\n");
3760 /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
3761 if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
3763 win_skip("Some tests will crash on older crypt32 implementations\n");
3767 /* Basic parameter checking tests */
3768 test_msg_open_to_encode();
3769 test_msg_open_to_decode();
3770 test_msg_get_param();
3774 /* Message-type specific tests */
3778 test_enveloped_msg();
3781 test_msg_get_and_verify_signer();