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 void test_data_msg_update(void)
372 CMSG_STREAM_INFO streamInfo = { 0 };
374 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
376 /* Can't update a message that wasn't opened detached with final = FALSE */
377 SetLastError(0xdeadbeef);
378 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
379 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
380 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
381 /* Updating it with final = TRUE succeeds */
382 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
383 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
384 /* Any subsequent update will fail, as the last was final */
385 SetLastError(0xdeadbeef);
386 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
387 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
388 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
391 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
393 /* Can't update a message with no data */
394 SetLastError(0xdeadbeef);
395 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
396 /* This test returns FALSE on XP and earlier but TRUE on Vista, so can't be tested.
397 * GetLastError is either E_INVALIDARG (NT) or unset (9x/Vista), so it doesn't
398 * make sense to test this.
401 /* Curiously, a valid update will now fail as well, presumably because of
402 * the last (invalid, but final) update.
404 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
405 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
406 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
409 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
410 CMSG_DATA, NULL, NULL, NULL);
413 /* Doesn't appear to be able to update CMSG-DATA with non-final updates.
414 * On Win9x, this sometimes succeeds, sometimes fails with
415 * GetLastError() == 0, so it's not worth checking there.
417 SetLastError(0xdeadbeef);
418 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
420 (GetLastError() == E_INVALIDARG ||
421 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
422 "Expected E_INVALIDARG, got %x\n", GetLastError());
423 SetLastError(0xdeadbeef);
424 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
426 (GetLastError() == E_INVALIDARG ||
427 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
428 "Expected E_INVALIDARG, got %x\n", GetLastError());
431 skip("not updating CMSG_DATA with a non-final update\n");
432 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
433 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
438 /* Calling update after opening with an empty stream info (with a bogus
439 * output function) yields an error:
441 /* Crashes on some Win9x */
442 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
444 SetLastError(0xdeadbeef);
445 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
446 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
447 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
448 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
452 /* Calling update with a valid output function succeeds, even if the data
453 * exceeds the size specified in the stream info.
455 streamInfo.pfnStreamOutput = nop_stream_output;
456 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
458 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
459 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
460 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
461 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
465 static void test_data_msg_get_param(void)
470 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
472 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
475 /* Content and bare content are always gettable when not streaming */
477 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
478 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
480 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
481 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
482 /* But for this type of message, the signer and hash aren't applicable,
483 * and the type isn't available.
486 SetLastError(0xdeadbeef);
487 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
488 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
489 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
490 SetLastError(0xdeadbeef);
491 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
492 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
493 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
494 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
495 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
496 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
499 /* Can't get content or bare content when streaming */
500 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
502 SetLastError(0xdeadbeef);
503 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
504 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
505 "Expected E_INVALIDARG, got %x\n", GetLastError());
506 SetLastError(0xdeadbeef);
507 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
508 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
509 "Expected E_INVALIDARG, got %x\n", GetLastError());
513 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
514 static const BYTE dataEmptyContent[] = {
515 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
517 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
518 static const BYTE dataContent[] = {
519 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
520 0x04,0x04,0x01,0x02,0x03,0x04 };
525 CRYPT_DATA_BLOB *updates;
528 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
529 DWORD cb, BOOL final)
531 struct update_accum *accum = (struct update_accum *)pvArg;
535 accum->updates = CryptMemRealloc(accum->updates,
536 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
538 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
541 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
543 blob->pbData = CryptMemAlloc(cb);
546 memcpy(blob->pbData, pb, cb);
555 /* The updates of a (bogus) definite-length encoded message */
556 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
557 0x07,0x01,0xa0,0x02,0x04,0x00 };
558 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
559 static CRYPT_DATA_BLOB b1[] = {
564 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
565 /* The updates of a definite-length encoded message */
566 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
567 0x07,0x01,0xa0,0x06,0x04,0x04 };
568 static CRYPT_DATA_BLOB b2[] = {
572 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
573 /* The updates of an indefinite-length encoded message */
574 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
575 0x07,0x01,0xa0,0x80,0x24,0x80 };
576 static BYTE u5[] = { 0x04,0x04 };
577 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
578 static CRYPT_DATA_BLOB b3[] = {
586 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
588 static void check_updates(LPCSTR header, const struct update_accum *expected,
589 const struct update_accum *got)
593 ok(expected->cUpdates == got->cUpdates,
594 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
596 if (expected->cUpdates == got->cUpdates)
597 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
599 ok(expected->updates[i].cbData == got->updates[i].cbData,
600 "%s, update %d: expected %d bytes, got %d\n", header, i,
601 expected->updates[i].cbData, got->updates[i].cbData);
602 if (expected->updates[i].cbData && expected->updates[i].cbData ==
603 got->updates[i].cbData)
604 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
605 got->updates[i].cbData), "%s, update %d: unexpected value\n",
610 /* Frees the updates stored in accum */
611 static void free_updates(struct update_accum *accum)
615 for (i = 0; i < accum->cUpdates; i++)
616 CryptMemFree(accum->updates[i].pbData);
617 CryptMemFree(accum->updates);
618 accum->updates = NULL;
622 static void test_data_msg_encoding(void)
626 static char oid[] = "1.2.3";
627 struct update_accum accum = { 0, NULL };
628 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
630 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
632 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
633 dataEmptyBareContent, sizeof(dataEmptyBareContent));
634 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
635 sizeof(dataEmptyContent));
636 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
637 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
638 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
639 dataBareContent, sizeof(dataBareContent));
640 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
641 sizeof(dataContent));
643 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
644 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
645 CMSG_DATA, NULL, NULL, NULL);
646 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
647 dataEmptyBareContent, sizeof(dataEmptyBareContent));
648 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
649 sizeof(dataEmptyContent));
650 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
651 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
652 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
653 dataBareContent, sizeof(dataBareContent));
654 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
655 sizeof(dataContent));
657 /* The inner OID is apparently ignored */
658 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
660 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
661 dataEmptyBareContent, sizeof(dataEmptyBareContent));
662 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
663 dataEmptyContent, sizeof(dataEmptyContent));
664 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
665 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
666 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
667 dataBareContent, sizeof(dataBareContent));
668 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
669 sizeof(dataContent));
671 /* A streaming message is DER encoded if the length is not 0xffffffff, but
672 * curiously, updates aren't validated to make sure they don't exceed the
673 * stated length. (The resulting output will of course fail to decode.)
675 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
677 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
678 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
680 check_updates("bogus data message with definite length", &a1, &accum);
681 free_updates(&accum);
682 /* A valid definite-length encoding: */
683 streamInfo.cbContent = sizeof(msgData);
684 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
686 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
688 check_updates("data message with definite length", &a2, &accum);
689 free_updates(&accum);
690 /* An indefinite-length encoding: */
691 streamInfo.cbContent = 0xffffffff;
692 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
694 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
695 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
697 check_updates("data message with indefinite length", &a3, &accum);
698 free_updates(&accum);
701 static void test_data_msg(void)
703 test_data_msg_open();
704 test_data_msg_update();
705 test_data_msg_get_param();
706 test_data_msg_encoding();
709 static void test_hash_msg_open(void)
712 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
713 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
715 SetLastError(0xdeadbeef);
716 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
718 ok(!msg && GetLastError() == E_INVALIDARG,
719 "Expected E_INVALIDARG, got %x\n", GetLastError());
720 hashInfo.cbSize = sizeof(hashInfo);
721 SetLastError(0xdeadbeef);
722 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
724 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
725 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
726 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
727 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
729 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
731 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
732 CMSG_HASHED, &hashInfo, NULL, NULL);
733 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
735 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
736 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
737 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
741 static void test_hash_msg_update(void)
745 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
746 { oid_rsa_md5, { 0, NULL } }, NULL };
747 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
749 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
750 CMSG_HASHED, &hashInfo, NULL, NULL);
751 /* Detached hashed messages opened in non-streaming mode allow non-final
754 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
755 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
756 /* including non-final updates with no data.. */
757 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
758 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
759 /* and final updates with no data. */
760 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
761 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
762 /* But no updates are allowed after the final update. */
763 SetLastError(0xdeadbeef);
764 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
765 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
766 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
767 SetLastError(0xdeadbeef);
768 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
769 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
770 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
772 /* Non-detached messages, in contrast, don't allow non-final updates in
773 * non-streaming mode.
775 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
777 SetLastError(0xdeadbeef);
778 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
779 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
780 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
781 /* Final updates (including empty ones) are allowed. */
782 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
783 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
785 /* And, of course, streaming mode allows non-final updates */
786 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
788 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
789 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
791 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
792 * to be a bug, it isn't actually used - see encoding tests.)
794 streamInfo.pfnStreamOutput = NULL;
795 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
797 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
798 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
802 static const BYTE emptyHashParam[] = {
803 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
806 static void test_hash_msg_get_param(void)
810 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
811 { oid_rsa_md5, { 0, NULL } }, NULL };
813 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
816 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
818 /* Content and bare content are always gettable for non-streamed messages */
820 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
821 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
822 "CryptMsgGetParam failed: %08x\n", GetLastError());
824 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
825 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
826 "CryptMsgGetParam failed: %08x\n", GetLastError());
827 /* For an encoded hash message, the hash data aren't available */
828 SetLastError(0xdeadbeef);
829 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
830 ok(!ret && (GetLastError() == CRYPT_E_INVALID_MSG_TYPE ||
831 GetLastError() == OSS_LIMITED /* Win9x */),
832 "Expected CRYPT_E_INVALID_MSG_TYPE or OSS_LIMITED, got %08x\n",
834 /* The hash is also available. */
836 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
837 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
838 ok(size == sizeof(buf), "Unexpected size %d\n", size);
839 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
840 if (size == sizeof(buf))
841 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
842 /* By getting the hash, further updates are not allowed */
843 SetLastError(0xdeadbeef);
844 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
846 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
847 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
848 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
849 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
850 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
852 /* Even after a final update, the hash data aren't available */
853 SetLastError(0xdeadbeef);
854 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
855 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
856 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
857 /* The version is also available, and should be zero for this message. */
859 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
860 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
861 "CryptMsgGetParam failed: %08x\n", GetLastError());
862 size = sizeof(value);
863 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
864 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
865 "CryptMsgGetParam failed: %08x\n", GetLastError());
867 ok(value == 0, "Expected version 0, got %d\n", value);
868 /* As usual, the type isn't available. */
869 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
870 ok(!ret, "Expected failure\n");
873 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
875 /* Streamed messages don't allow you to get the content or bare content. */
876 SetLastError(0xdeadbeef);
877 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
878 ok(!ret && (GetLastError() == E_INVALIDARG ||
879 GetLastError() == OSS_LIMITED /* Win9x */),
880 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
881 SetLastError(0xdeadbeef);
882 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
883 ok(!ret && (GetLastError() == E_INVALIDARG ||
884 GetLastError() == OSS_LIMITED /* Win9x */),
885 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
886 /* The hash is still available. */
888 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
889 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
890 ok(size == sizeof(buf), "Unexpected size %d\n", size);
891 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
892 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
893 if (size == sizeof(buf))
894 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
895 /* After updating the hash, further updates aren't allowed on streamed
898 SetLastError(0xdeadbeef);
899 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
901 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
902 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
903 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
904 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
905 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
910 static const BYTE hashEmptyBareContent[] = {
911 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
912 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
913 static const BYTE hashEmptyContent[] = {
914 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
915 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
916 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
917 static const BYTE hashBareContent[] = {
918 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
919 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
920 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
921 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
922 static const BYTE hashContent[] = {
923 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
924 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
925 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
926 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
927 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
929 static const BYTE detachedHashNonFinalBareContent[] = {
930 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
931 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
932 0x07,0x01,0x04,0x00 };
933 static const BYTE detachedHashNonFinalContent[] = {
934 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
935 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
936 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
937 0x07,0x01,0x04,0x00 };
938 static const BYTE detachedHashBareContent[] = {
939 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
940 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
941 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
942 0x9d,0x2a,0x8f,0x26,0x2f };
943 static const BYTE detachedHashContent[] = {
944 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
945 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
946 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
947 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
948 0x9d,0x2a,0x8f,0x26,0x2f };
950 static void test_hash_msg_encoding(void)
953 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
955 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
956 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
958 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
959 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
961 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
962 hashEmptyBareContent, sizeof(hashEmptyBareContent));
963 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
964 hashEmptyContent, sizeof(hashEmptyContent));
965 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
966 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
967 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
968 hashBareContent, sizeof(hashBareContent));
969 check_param("hash content", msg, CMSG_CONTENT_PARAM,
970 hashContent, sizeof(hashContent));
972 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
973 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
974 CMSG_HASHED, &hashInfo, NULL, NULL);
975 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
976 hashEmptyBareContent, sizeof(hashEmptyBareContent));
977 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
978 hashEmptyContent, sizeof(hashEmptyContent));
979 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
980 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
981 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
982 hashBareContent, sizeof(hashBareContent));
983 check_param("hash content", msg, CMSG_CONTENT_PARAM,
984 hashContent, sizeof(hashContent));
986 /* Same test, but with CMSG_DETACHED_FLAG set */
987 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
988 CMSG_HASHED, &hashInfo, NULL, NULL);
989 check_param("detached hash empty bare content", msg,
990 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
991 sizeof(hashEmptyBareContent));
992 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
993 hashEmptyContent, sizeof(hashEmptyContent));
994 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
995 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
996 check_param("detached hash not final bare content", msg,
997 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
998 sizeof(detachedHashNonFinalBareContent));
999 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
1000 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
1001 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1002 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1003 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1004 detachedHashBareContent, sizeof(detachedHashBareContent));
1005 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1006 detachedHashContent, sizeof(detachedHashContent));
1007 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1008 detachedHashBareContent, sizeof(detachedHashBareContent));
1009 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1010 detachedHashContent, sizeof(detachedHashContent));
1012 /* In what appears to be a bug, streamed updates to hash messages don't
1013 * call the output function.
1015 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
1017 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1018 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1019 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1020 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1022 check_updates("empty hash message", &empty_accum, &accum);
1023 free_updates(&accum);
1025 streamInfo.cbContent = sizeof(msgData);
1026 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
1028 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1029 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1031 check_updates("hash message", &empty_accum, &accum);
1032 free_updates(&accum);
1034 streamInfo.cbContent = sizeof(msgData);
1035 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
1036 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
1037 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1038 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1040 check_updates("detached hash message", &empty_accum, &accum);
1041 free_updates(&accum);
1044 static void test_hash_msg(void)
1046 test_hash_msg_open();
1047 test_hash_msg_update();
1048 test_hash_msg_get_param();
1049 test_hash_msg_encoding();
1052 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1054 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1056 static BYTE serialNum[] = { 1 };
1057 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1058 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1060 static void test_signed_msg_open(void)
1064 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1065 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1066 CERT_INFO certInfo = { 0 };
1068 SetLastError(0xdeadbeef);
1069 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1071 ok(!msg && GetLastError() == E_INVALIDARG,
1072 "Expected E_INVALIDARG, got %x\n", GetLastError());
1073 signInfo.cbSize = sizeof(signInfo);
1074 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1076 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1079 signInfo.cSigners = 1;
1080 signInfo.rgSigners = &signer;
1081 /* With signer.pCertInfo unset, attempting to open this message this
1084 signer.pCertInfo = &certInfo;
1085 /* The cert info must contain a serial number and an issuer. */
1086 SetLastError(0xdeadbeef);
1087 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1089 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1090 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1091 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1092 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1095 certInfo.SerialNumber.cbData = sizeof(serialNum);
1096 certInfo.SerialNumber.pbData = serialNum;
1097 SetLastError(0xdeadbeef);
1098 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1100 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1101 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1102 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1103 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1106 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1107 certInfo.Issuer.pbData = encodedCommonName;
1108 SetLastError(0xdeadbeef);
1109 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1111 ok(!msg && (GetLastError() == E_INVALIDARG ||
1112 GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1113 "Expected E_INVALIDARG or CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1115 /* The signer's hCryptProv must be set to something. Whether it's usable
1116 * or not will be checked after the hash algorithm is checked (see next
1119 signer.hCryptProv = 1;
1120 SetLastError(0xdeadbeef);
1121 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1123 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1124 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1125 /* The signer's hash algorithm must also be set. */
1126 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1127 SetLastError(0xdeadbeef);
1128 /* Crashes in advapi32 in wine, don't do it */
1130 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1131 &signInfo, NULL, NULL);
1132 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1133 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1135 /* The signer's hCryptProv must also be valid. */
1136 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1137 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1138 if (!ret && GetLastError() == NTE_EXISTS) {
1139 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1142 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1145 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1147 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1151 /* pCertInfo must still be set, but can be empty if the SignerId's issuer
1152 * and serial number are set.
1154 certInfo.Issuer.cbData = 0;
1155 certInfo.SerialNumber.cbData = 0;
1156 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1157 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1158 sizeof(encodedCommonName);
1159 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1160 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1162 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1163 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1165 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1168 CryptReleaseContext(signer.hCryptProv, 0);
1169 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1170 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1173 static const BYTE privKey[] = {
1174 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1175 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1176 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1177 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1178 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1179 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1180 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1181 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1182 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1183 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1184 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1185 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1186 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1187 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1188 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1189 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1190 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1191 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1192 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1193 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1194 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1195 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1196 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1197 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1198 static BYTE pubKey[] = {
1199 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1200 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1201 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1202 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1203 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1205 static void test_signed_msg_update(void)
1209 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1210 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1211 CERT_INFO certInfo = { 0 };
1214 certInfo.SerialNumber.cbData = sizeof(serialNum);
1215 certInfo.SerialNumber.pbData = serialNum;
1216 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1217 certInfo.Issuer.pbData = encodedCommonName;
1218 signer.pCertInfo = &certInfo;
1219 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1220 signInfo.cSigners = 1;
1221 signInfo.rgSigners = &signer;
1223 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1224 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1225 if (!ret && GetLastError() == NTE_EXISTS) {
1226 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1229 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1232 skip("No context for tests\n");
1236 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1237 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1238 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1239 /* Detached CMSG_SIGNED allows non-final updates. */
1240 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1241 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1242 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1243 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1244 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1245 /* The final update requires a private key in the hCryptProv, in order to
1246 * generate the signature.
1248 SetLastError(0xdeadbeef);
1249 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1251 (GetLastError() == NTE_BAD_KEYSET ||
1252 GetLastError() == NTE_NO_KEY ||
1253 broken(GetLastError() == ERROR_SUCCESS)), /* Some Win9x */
1254 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1255 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1257 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1258 /* The final update should be able to succeed now that a key exists, but
1259 * the previous (invalid) final update prevents it.
1261 SetLastError(0xdeadbeef);
1262 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1263 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1264 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1267 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1268 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1269 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1270 /* Detached CMSG_SIGNED allows non-final updates. */
1271 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1272 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1273 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1274 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1275 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1276 /* Now that the private key exists, the final update can succeed (even
1279 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1280 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1281 /* But no updates are allowed after the final update. */
1282 SetLastError(0xdeadbeef);
1283 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1284 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1285 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1286 SetLastError(0xdeadbeef);
1287 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1288 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1289 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1292 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1294 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1295 /* Non-detached messages don't allow non-final updates.. */
1296 SetLastError(0xdeadbeef);
1297 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1298 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1299 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1300 /* but they do allow final ones. */
1301 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1302 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1304 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1306 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1307 /* They also allow final updates with no data. */
1308 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1309 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1312 CryptDestroyKey(key);
1313 CryptReleaseContext(signer.hCryptProv, 0);
1314 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1315 CRYPT_DELETEKEYSET);
1318 static const BYTE signedEmptyBareContent[] = {
1319 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1320 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1321 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1322 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1323 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1324 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1325 static const BYTE signedEmptyContent[] = {
1326 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1327 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1328 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1329 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1330 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1331 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1332 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1333 static const BYTE detachedSignedBareContent[] = {
1334 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1335 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1336 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1337 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1338 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1339 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1340 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1341 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1342 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1343 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1344 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1345 static const BYTE detachedSignedContent[] = {
1346 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1347 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1348 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1349 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1350 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1351 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1352 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1353 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1354 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1355 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1356 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1357 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1358 static const BYTE signedBareContent[] = {
1359 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1360 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1361 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1362 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1363 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1364 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1365 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1366 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1367 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1368 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1369 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1370 static const BYTE signedContent[] = {
1371 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1372 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1373 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1374 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1375 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1376 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1377 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1378 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1379 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1380 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1381 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1382 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1384 static const BYTE signedHash[] = {
1385 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1387 static const BYTE signedKeyIdEmptyContent[] = {
1388 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
1389 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1390 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
1391 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1392 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1393 static const BYTE signedEncodedSigner[] = {
1394 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1395 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1396 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1397 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1398 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1399 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1400 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1401 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1402 static const BYTE signedWithAuthAttrsBareContent[] = {
1403 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1404 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1405 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1406 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1407 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1408 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1409 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1410 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1411 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1412 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1413 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1414 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1415 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1416 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1417 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1418 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1419 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1420 0xff,0xc6,0x33,0x63,0x34 };
1421 static BYTE cert[] = {
1422 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1423 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1424 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1425 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1426 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1427 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1428 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1429 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1430 0xff,0x02,0x01,0x01 };
1431 static BYTE v1CertWithPubKey[] = {
1432 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1433 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1434 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1435 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1436 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1437 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1438 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1439 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1440 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1441 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1443 static const BYTE signedWithCertEmptyBareContent[] = {
1444 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1445 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1446 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1447 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1448 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1449 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1450 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1451 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1452 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1453 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1454 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1455 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1456 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1457 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1458 static const BYTE signedWithCertBareContent[] = {
1459 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1460 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1461 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1462 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1463 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1464 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1465 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1466 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1467 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1468 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1469 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1470 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1471 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1472 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1473 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1474 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1475 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1476 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1477 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1478 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1479 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1480 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1481 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1482 0x30,0x30,0x30,0x30,0x5a };
1483 static const BYTE signedWithCrlEmptyBareContent[] = {
1484 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1485 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1486 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1487 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1488 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1489 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1490 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1491 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1492 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1493 static const BYTE signedWithCrlBareContent[] = {
1494 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1495 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1496 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1497 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1498 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1499 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1500 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1501 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1502 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1503 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1504 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1505 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1506 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1507 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1509 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1510 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1511 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1512 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1513 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1514 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1515 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1516 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1517 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1518 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1519 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1520 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1521 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1522 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1523 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1524 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1525 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1526 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1528 static const BYTE signedWithCertAndCrlBareContent[] = {
1529 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1530 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1531 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1532 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1533 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1534 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1535 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1536 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1537 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1538 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1539 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1540 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1541 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1542 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1543 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1544 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1545 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1546 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1547 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1548 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1549 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1550 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1551 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1552 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1553 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1554 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1555 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1556 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1557 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1558 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1559 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1560 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1561 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1562 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1563 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1564 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1565 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1566 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1567 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1568 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1569 static BYTE v1CertWithValidPubKey[] = {
1570 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1571 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1572 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1573 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1574 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1575 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1576 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1577 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1578 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1579 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1580 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1581 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1582 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1583 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1584 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1585 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1586 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1587 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1588 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1589 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1590 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1591 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1592 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1593 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1594 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1595 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1596 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1597 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1598 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1599 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1600 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1601 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1602 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1603 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1604 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1605 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1607 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1608 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1609 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1610 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1611 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1612 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1613 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1614 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1615 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1616 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1617 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1618 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1619 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1620 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1621 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1622 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1623 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1624 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1625 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1626 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1627 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1628 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1629 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1630 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1631 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1632 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1633 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1634 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1636 static void test_signed_msg_encoding(void)
1639 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1640 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1641 CERT_INFO certInfo = { 0 };
1642 CERT_BLOB encodedCert = { sizeof(cert), cert };
1643 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1644 char oid_common_name[] = szOID_COMMON_NAME;
1645 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1646 encodedCommonName };
1647 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1652 certInfo.SerialNumber.cbData = sizeof(serialNum);
1653 certInfo.SerialNumber.pbData = serialNum;
1654 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1655 certInfo.Issuer.pbData = encodedCommonName;
1656 signer.pCertInfo = &certInfo;
1657 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1658 signInfo.cSigners = 1;
1659 signInfo.rgSigners = &signer;
1661 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1662 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1663 if (!ret && GetLastError() == NTE_EXISTS) {
1664 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1667 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1670 skip("No context for tests\n");
1674 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1676 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1678 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1679 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1680 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1682 check_param("detached signed empty bare content", msg,
1683 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1684 sizeof(signedEmptyBareContent));
1685 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1686 signedEmptyContent, sizeof(signedEmptyContent));
1687 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1688 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1689 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1690 signedHash, sizeof(signedHash));
1691 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1692 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1693 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1694 detachedSignedContent, sizeof(detachedSignedContent));
1695 SetLastError(0xdeadbeef);
1696 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1697 ok(!ret && (GetLastError() == CRYPT_E_INVALID_INDEX ||
1698 broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */)),
1699 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1700 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1701 signedEncodedSigner, sizeof(signedEncodedSigner));
1705 certInfo.SerialNumber.cbData = 0;
1706 certInfo.Issuer.cbData = 0;
1707 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1708 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1709 U(signer.SignerId).KeyId.pbData = serialNum;
1710 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1712 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1713 check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM,
1714 signedKeyIdEmptyContent, sizeof(signedKeyIdEmptyContent));
1717 certInfo.SerialNumber.cbData = sizeof(serialNum);
1718 certInfo.SerialNumber.pbData = serialNum;
1719 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1720 certInfo.Issuer.pbData = encodedCommonName;
1721 signer.SignerId.dwIdChoice = 0;
1722 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1724 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1726 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1727 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1728 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1729 signedEmptyContent, sizeof(signedEmptyContent));
1730 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1731 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1732 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1733 signedBareContent, sizeof(signedBareContent));
1734 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1735 signedContent, sizeof(signedContent));
1739 signer.cAuthAttr = 1;
1740 signer.rgAuthAttr = &attr;
1741 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1743 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1745 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1746 check_param("signed with auth attrs bare content", msg,
1747 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1748 sizeof(signedWithAuthAttrsBareContent));
1752 signer.cAuthAttr = 0;
1753 signInfo.rgCertEncoded = &encodedCert;
1754 signInfo.cCertEncoded = 1;
1755 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1757 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1759 check_param("signed with cert empty bare content", msg,
1760 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1761 sizeof(signedWithCertEmptyBareContent));
1762 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1763 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1764 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1765 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1769 signInfo.cCertEncoded = 0;
1770 signInfo.rgCrlEncoded = &encodedCrl;
1771 signInfo.cCrlEncoded = 1;
1772 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1774 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1776 check_param("signed with crl empty bare content", msg,
1777 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1778 sizeof(signedWithCrlEmptyBareContent));
1779 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1780 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1781 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1782 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1786 signInfo.cCertEncoded = 1;
1787 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1789 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1791 check_param("signed with cert and crl empty bare content", msg,
1792 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1793 sizeof(signedWithCertAndCrlEmptyBareContent));
1794 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1795 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1796 check_param("signed with cert and crl bare content", msg,
1797 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1798 sizeof(signedWithCertAndCrlBareContent));
1802 /* Test with a cert with a (bogus) public key */
1803 signInfo.cCrlEncoded = 0;
1804 encodedCert.cbData = sizeof(v1CertWithPubKey);
1805 encodedCert.pbData = v1CertWithPubKey;
1806 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1808 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1809 check_param("signedWithCertWithPubKeyBareContent", msg,
1810 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1811 sizeof(signedWithCertWithPubKeyBareContent));
1814 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1815 encodedCert.pbData = v1CertWithValidPubKey;
1816 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1818 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1819 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1820 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1821 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1822 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1823 check_param("signedWithCertWithValidPubKeyContent", msg,
1824 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1825 sizeof(signedWithCertWithValidPubKeyContent));
1828 CryptDestroyKey(key);
1829 CryptReleaseContext(signer.hCryptProv, 0);
1830 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1831 CRYPT_DELETEKEYSET);
1834 static void test_signed_msg_get_param(void)
1838 DWORD size, value = 0;
1839 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1840 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1841 CERT_INFO certInfo = { 0 };
1843 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1845 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1847 /* Content and bare content are always gettable */
1849 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1850 ok(ret || broken(!ret /* Win9x */), "CryptMsgGetParam failed: %08x\n",
1854 skip("message parameters are broken, skipping tests\n");
1858 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1859 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1860 /* For "signed" messages, so is the version. */
1862 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1863 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1864 size = sizeof(value);
1865 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1866 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1867 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1868 /* But for this message, with no signers, the hash and signer aren't
1872 SetLastError(0xdeadbeef);
1873 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1874 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1875 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1876 SetLastError(0xdeadbeef);
1877 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1878 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1879 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1880 /* As usual, the type isn't available. */
1881 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1882 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1883 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1887 certInfo.SerialNumber.cbData = sizeof(serialNum);
1888 certInfo.SerialNumber.pbData = serialNum;
1889 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1890 certInfo.Issuer.pbData = encodedCommonName;
1891 signer.pCertInfo = &certInfo;
1892 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1893 signInfo.cSigners = 1;
1894 signInfo.rgSigners = &signer;
1896 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1897 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1898 if (!ret && GetLastError() == NTE_EXISTS) {
1899 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1902 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1905 skip("No context for tests\n");
1909 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1911 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1913 /* This message, with one signer, has the hash and signer for index 0
1914 * available, but not for other indexes.
1917 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1918 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1919 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1920 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1922 SetLastError(0xdeadbeef);
1923 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1924 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1925 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1926 SetLastError(0xdeadbeef);
1927 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1928 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1929 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1930 /* As usual, the type isn't available. */
1931 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1932 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1933 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1937 /* Opening the message using the CMS fields.. */
1938 certInfo.SerialNumber.cbData = 0;
1939 certInfo.Issuer.cbData = 0;
1940 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1941 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1942 sizeof(encodedCommonName);
1943 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1944 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1946 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1947 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1948 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1949 if (!ret && GetLastError() == NTE_EXISTS)
1950 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1952 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1953 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1954 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1955 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1956 /* still results in the version being 1 when the issuer and serial number
1957 * are used and no additional CMS fields are used.
1959 size = sizeof(value);
1960 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1961 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE),
1962 "CryptMsgGetParam failed: %08x\n", GetLastError());
1964 ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value);
1965 /* Apparently the encoded signer can be retrieved.. */
1966 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1967 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1968 /* but the signer info, CMS signer info, and cert ID can't be. */
1969 SetLastError(0xdeadbeef);
1970 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1971 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1972 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1973 SetLastError(0xdeadbeef);
1974 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1975 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1976 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1977 SetLastError(0xdeadbeef);
1978 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1979 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1980 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1983 /* Using the KeyId field of the SignerId results in the version becoming
1986 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1987 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1988 U(signer.SignerId).KeyId.pbData = serialNum;
1989 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1990 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1991 if (!ret && GetLastError() == NTE_EXISTS)
1992 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1994 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1995 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1996 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1997 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1998 size = sizeof(value);
1999 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
2000 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2002 ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value);
2003 /* Even for a CMS message, the signer can be retrieved.. */
2004 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
2005 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2006 /* but the signer info, CMS signer info, and cert ID can't be. */
2007 SetLastError(0xdeadbeef);
2008 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2009 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2010 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2011 SetLastError(0xdeadbeef);
2012 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2013 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2014 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2015 SetLastError(0xdeadbeef);
2016 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
2017 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2018 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2021 CryptReleaseContext(signer.hCryptProv, 0);
2022 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
2023 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2026 static void test_signed_msg(void)
2028 test_signed_msg_open();
2029 test_signed_msg_update();
2030 test_signed_msg_encoding();
2031 test_signed_msg_get_param();
2034 static char oid_rsa_rc4[] = szOID_RSA_RC4;
2036 static void test_enveloped_msg_open(void)
2040 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { 0 };
2041 PCCERT_CONTEXT context;
2043 SetLastError(0xdeadbeef);
2044 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2045 &envelopedInfo, NULL, NULL);
2047 ok(!msg && GetLastError() == E_INVALIDARG,
2048 "expected E_INVALIDARG, got %08x\n", GetLastError());
2050 envelopedInfo.cbSize = sizeof(envelopedInfo);
2051 SetLastError(0xdeadbeef);
2052 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2053 &envelopedInfo, NULL, NULL);
2056 (GetLastError() == CRYPT_E_UNKNOWN_ALGO ||
2057 GetLastError() == E_INVALIDARG), /* Win9x */
2058 "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", GetLastError());
2060 envelopedInfo.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4;
2061 SetLastError(0xdeadbeef);
2062 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2063 &envelopedInfo, NULL, NULL);
2066 broken(!msg), /* Win9x */
2067 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2070 envelopedInfo.cRecipients = 1;
2073 SetLastError(0xdeadbeef);
2074 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2075 &envelopedInfo, NULL, NULL);
2077 ok(!msg && GetLastError() == E_INVALIDARG,
2078 "expected E_INVALIDARG, got %08x\n", GetLastError());
2081 SetLastError(0xdeadbeef);
2082 context = CertCreateCertificateContext(X509_ASN_ENCODING,
2083 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
2084 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2086 envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo;
2087 SetLastError(0xdeadbeef);
2088 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2089 &envelopedInfo, NULL, NULL);
2091 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2094 SetLastError(0xdeadbeef);
2095 ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL,
2096 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
2097 ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
2098 SetLastError(0xdeadbeef);
2099 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2100 &envelopedInfo, NULL, NULL);
2102 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2105 CryptReleaseContext(envelopedInfo.hCryptProv, 0);
2106 CertFreeCertificateContext(context);
2109 static void test_enveloped_msg_update(void)
2113 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2114 { oid_rsa_rc4, { 0, NULL } }, NULL };
2115 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
2117 SetLastError(0xdeadbeef);
2118 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2119 &envelopedInfo, NULL, NULL);
2122 broken(!msg), /* Win9x */
2123 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2126 SetLastError(0xdeadbeef);
2127 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2129 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2130 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2131 SetLastError(0xdeadbeef);
2132 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2134 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2135 SetLastError(0xdeadbeef);
2136 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2138 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2139 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2142 SetLastError(0xdeadbeef);
2143 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2144 &envelopedInfo, NULL, NULL);
2147 broken(!msg), /* Win9x */
2148 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2151 SetLastError(0xdeadbeef);
2152 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2154 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2155 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2156 SetLastError(0xdeadbeef);
2157 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2159 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2160 SetLastError(0xdeadbeef);
2161 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2163 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2164 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2167 SetLastError(0xdeadbeef);
2168 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2169 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2172 broken(!msg), /* Win9x */
2173 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2176 SetLastError(0xdeadbeef);
2177 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2179 ok(!ret && GetLastError() == E_INVALIDARG,
2180 "expected E_INVALIDARG, got %08x\n", GetLastError());
2181 SetLastError(0xdeadbeef);
2182 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2184 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2187 SetLastError(0xdeadbeef);
2188 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2189 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);
2199 ok(!ret && GetLastError() == E_INVALIDARG,
2200 "expected E_INVALIDARG, got %08x\n", GetLastError());
2201 SetLastError(0xdeadbeef);
2202 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2204 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2207 SetLastError(0xdeadbeef);
2208 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2209 &envelopedInfo, NULL, &streamInfo);
2212 broken(!msg), /* Win9x */
2213 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2216 SetLastError(0xdeadbeef);
2217 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2219 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2220 SetLastError(0xdeadbeef);
2221 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2223 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2226 SetLastError(0xdeadbeef);
2227 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2228 &envelopedInfo, NULL, &streamInfo);
2231 broken(!msg), /* Win9x */
2232 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2235 SetLastError(0xdeadbeef);
2236 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2238 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2239 SetLastError(0xdeadbeef);
2240 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2242 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2247 static const BYTE envelopedEmptyBareContent[] = {
2248 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2249 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2250 0x03,0x04,0x05,0x00,0x80,0x00 };
2251 static const BYTE envelopedEmptyContent[] = {
2252 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24,
2253 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2254 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2255 0x03,0x04,0x05,0x00,0x80,0x00 };
2257 static void test_enveloped_msg_encoding(void)
2260 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2261 { oid_rsa_rc4, { 0, NULL } }, NULL };
2263 SetLastError(0xdeadbeef);
2264 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2265 &envelopedInfo, NULL, NULL);
2268 broken(!msg), /* Win9x */
2269 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2272 check_param("enveloped empty bare content", msg,
2273 CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent,
2274 sizeof(envelopedEmptyBareContent));
2275 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
2276 envelopedEmptyContent, sizeof(envelopedEmptyContent));
2281 static void test_enveloped_msg(void)
2283 test_enveloped_msg_open();
2284 test_enveloped_msg_update();
2285 test_enveloped_msg_encoding();
2288 static CRYPT_DATA_BLOB b4 = { 0, NULL };
2289 static const struct update_accum a4 = { 1, &b4 };
2291 static const BYTE bogusOIDContent[] = {
2292 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2294 static const BYTE bogusHashContent[] = {
2295 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2296 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2297 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2298 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2299 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2300 static const BYTE envelopedBareContentWithoutData[] = {
2301 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2302 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2303 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2304 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2305 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b,
2306 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f,
2307 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94,
2308 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72,
2309 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18,
2310 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3,
2311 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6,
2312 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49,
2313 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e,
2314 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2315 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 };
2317 static void test_decode_msg_update(void)
2321 CMSG_STREAM_INFO streamInfo = { 0 };
2323 struct update_accum accum = { 0, NULL };
2325 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2326 /* Update with a full message in a final update */
2327 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2328 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2329 /* Can't update after a final update */
2330 SetLastError(0xdeadbeef);
2331 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2332 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2333 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2336 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2337 /* Can't send a non-final update without streaming */
2338 SetLastError(0xdeadbeef);
2339 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2341 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2342 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2343 /* A subsequent final update succeeds */
2344 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2345 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2350 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2351 /* Updating a message that has a NULL stream callback fails */
2352 SetLastError(0xdeadbeef);
2353 /* Crashes on some Win9x */
2354 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2357 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2358 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2359 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2361 /* Changing the callback pointer after the fact yields the same error (so
2362 * the message must copy the stream info, not just store a pointer to it)
2364 streamInfo.pfnStreamOutput = nop_stream_output;
2365 SetLastError(0xdeadbeef);
2366 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2369 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2370 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2371 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2376 /* Empty non-final updates are allowed when streaming.. */
2377 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2378 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2379 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2380 /* but final updates aren't when not enough data has been received. */
2381 SetLastError(0xdeadbeef);
2382 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2384 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2385 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2388 /* Updating the message byte by byte is legal */
2389 streamInfo.pfnStreamOutput = accumulating_stream_output;
2390 streamInfo.pvArg = &accum;
2391 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2392 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2393 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2394 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2395 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2396 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2399 check_updates("byte-by-byte empty content", &a4, &accum);
2400 free_updates(&accum);
2402 /* Decoding bogus content fails in non-streaming mode.. */
2403 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2404 SetLastError(0xdeadbeef);
2405 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2406 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2407 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2408 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2411 /* and as the final update in streaming mode.. */
2412 streamInfo.pfnStreamOutput = nop_stream_output;
2413 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2414 SetLastError(0xdeadbeef);
2415 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2416 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2417 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2418 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2421 /* and even as a non-final update in streaming mode. */
2422 streamInfo.pfnStreamOutput = nop_stream_output;
2423 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2424 SetLastError(0xdeadbeef);
2425 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2427 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2428 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2429 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2433 /* An empty message can be opened with undetermined type.. */
2434 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2435 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2437 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2439 /* but decoding it as an explicitly typed message fails. */
2440 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2442 SetLastError(0xdeadbeef);
2443 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2445 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2446 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2447 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2450 /* On the other hand, decoding the bare content of an empty message fails
2451 * with unspecified type..
2453 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2454 SetLastError(0xdeadbeef);
2455 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2456 sizeof(dataEmptyBareContent), TRUE);
2457 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2458 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2459 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2462 /* but succeeds with explicit type. */
2463 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2465 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2466 sizeof(dataEmptyBareContent), TRUE);
2467 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2470 /* Decoding valid content with an unsupported OID fails */
2471 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2472 SetLastError(0xdeadbeef);
2473 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2474 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2475 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2478 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2479 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2480 SetLastError(0xdeadbeef);
2481 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2482 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2483 "CryptMsgUpdate failed: %08x\n", GetLastError());
2485 /* while with specified type it fails. */
2486 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2488 SetLastError(0xdeadbeef);
2489 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2490 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2491 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2492 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2493 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2496 /* On the other hand, decoding the bare content of an empty hash message
2497 * fails with unspecified type..
2499 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2500 SetLastError(0xdeadbeef);
2501 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2502 sizeof(hashEmptyBareContent), TRUE);
2503 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2504 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2505 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2506 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2509 /* but succeeds with explicit type. */
2510 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2512 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2513 sizeof(hashEmptyBareContent), TRUE);
2514 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2515 "CryptMsgUpdate failed: %x\n", GetLastError());
2518 /* And again, opening a (non-empty) hash message with unspecified type
2521 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2522 SetLastError(0xdeadbeef);
2523 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2524 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2526 /* while with specified type it fails.. */
2527 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2529 SetLastError(0xdeadbeef);
2530 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2531 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2532 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2533 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2534 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2537 /* and decoding the bare content of a non-empty hash message fails with
2538 * unspecified type..
2540 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2541 SetLastError(0xdeadbeef);
2542 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2543 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2544 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2545 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2546 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2549 /* but succeeds with explicit type. */
2550 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2552 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2553 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2556 /* Opening a (non-empty) hash message with unspecified type and a bogus
2557 * hash value succeeds..
2559 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2560 SetLastError(0xdeadbeef);
2561 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2562 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2565 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2566 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2567 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2569 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2570 SetLastError(0xdeadbeef);
2571 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2572 sizeof(signedWithCertAndCrlBareContent), TRUE);
2573 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2574 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2575 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2578 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2580 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2581 sizeof(signedWithCertAndCrlBareContent), TRUE);
2582 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2585 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2587 /* The first update succeeds.. */
2588 ret = CryptMsgUpdate(msg, detachedSignedContent,
2589 sizeof(detachedSignedContent), TRUE);
2590 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2591 /* as does a second (probably to update the detached portion).. */
2592 ret = CryptMsgUpdate(msg, detachedSignedContent,
2593 sizeof(detachedSignedContent), TRUE);
2594 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2595 /* while a third fails. */
2596 ret = CryptMsgUpdate(msg, detachedSignedContent,
2597 sizeof(detachedSignedContent), TRUE);
2598 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2599 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2602 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2603 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2604 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2605 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2606 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2607 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2608 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2609 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2610 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2612 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2613 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2614 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2617 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2619 SetLastError(0xdeadbeef);
2620 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2621 sizeof(envelopedEmptyBareContent), TRUE);
2622 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2625 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2627 SetLastError(0xdeadbeef);
2628 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2629 sizeof(envelopedEmptyContent), TRUE);
2632 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2633 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2634 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2637 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2638 SetLastError(0xdeadbeef);
2639 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2640 sizeof(envelopedEmptyBareContent), TRUE);
2642 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2643 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2644 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2647 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2648 SetLastError(0xdeadbeef);
2649 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2650 sizeof(envelopedEmptyContent), TRUE);
2651 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2654 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2656 SetLastError(0xdeadbeef);
2657 ret = CryptMsgUpdate(msg, envelopedBareContentWithoutData,
2658 sizeof(envelopedBareContentWithoutData), TRUE);
2659 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2663 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2664 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2666 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2667 const CMSG_SIGNER_INFO *expected)
2669 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2670 expected->dwVersion, got->dwVersion);
2671 ok(got->Issuer.cbData == expected->Issuer.cbData,
2672 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2673 got->Issuer.cbData);
2674 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2675 "Unexpected issuer\n");
2676 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2677 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2678 got->SerialNumber.cbData);
2679 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2680 got->SerialNumber.cbData), "Unexpected serial number\n");
2681 /* FIXME: check more things */
2684 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2685 const CMSG_CMS_SIGNER_INFO *expected)
2687 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2688 expected->dwVersion, got->dwVersion);
2689 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2690 "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2691 got->SignerId.dwIdChoice);
2692 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2694 if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2696 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2697 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2698 "Expected issuer size %d, got %d\n",
2699 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2700 U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2701 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2702 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2703 U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2704 "Unexpected issuer\n");
2705 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2706 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2707 "Expected serial number size %d, got %d\n",
2708 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2709 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2710 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2711 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2712 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2713 "Unexpected serial number\n");
2717 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2718 "expected key id size %d, got %d\n",
2719 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2720 ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2721 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2722 "unexpected key id\n");
2725 /* FIXME: check more things */
2728 static const BYTE signedWithCertAndCrlComputedHash[] = {
2729 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2731 static BYTE keyIdIssuer[] = {
2732 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2733 0x0a,0x07,0x01,0x04,0x01,0x01 };
2734 static const BYTE publicPrivateKeyPair[] = {
2735 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00,
2736 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b,
2737 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50,
2738 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54,
2739 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39,
2740 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7,
2741 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48,
2742 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17,
2743 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54,
2744 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33,
2745 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52,
2746 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e,
2747 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61,
2748 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb,
2749 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02,
2750 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90,
2751 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e,
2752 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce,
2753 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14,
2754 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5,
2755 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5,
2756 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94,
2757 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68,
2758 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71,
2759 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25,
2760 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc,
2761 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a,
2762 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64,
2763 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77,
2764 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68,
2765 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab,
2766 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9,
2767 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed,
2768 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01,
2769 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e,
2770 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71,
2771 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0,
2772 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87,
2773 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b,
2774 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e };
2775 static const BYTE envelopedMessage[] = {
2776 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,
2777 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,
2778 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,
2779 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,
2780 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
2781 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65,
2782 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae,
2783 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1,
2784 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51,
2785 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf,
2786 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b,
2787 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e,
2788 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e,
2789 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70,
2790 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,
2791 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,
2792 0x04,0x5f,0x80,0xf2,0x17 };
2793 static const BYTE envelopedBareMessage[] = {
2794 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2795 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2796 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2797 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2798 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d,
2799 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d,
2800 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5,
2801 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e,
2802 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2,
2803 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4,
2804 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70,
2805 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c,
2806 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55,
2807 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2808 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c,
2810 static const BYTE envelopedMessageWith3Recps[] = {
2811 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,
2812 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e,
2813 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,
2814 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,
2815 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,
2816 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e,
2817 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba,
2818 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f,
2819 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5,
2820 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21,
2821 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae,
2822 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0,
2823 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96,
2824 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae,
2825 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,
2826 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,
2827 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6,
2828 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
2829 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf,
2830 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9,
2831 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3,
2832 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02,
2833 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70,
2834 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3,
2835 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74,
2836 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94,
2837 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7,
2838 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,
2839 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,
2840 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
2841 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98,
2842 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5,
2843 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9,
2844 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3,
2845 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8,
2846 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac,
2847 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc,
2848 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5,
2849 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1,
2850 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
2851 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,
2852 0x80,0x04,0x4e,0x99,0x9d,0x4c };
2853 static const BYTE serialNumber[] = {
2854 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2,
2856 static const BYTE issuer[] = {
2857 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 };
2859 static void test_decode_msg_get_param(void)
2862 HCRYPTPROV hCryptProv;
2865 DWORD size = 0, value;
2867 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2869 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2870 SetLastError(0xdeadbeef);
2871 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2872 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2873 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2874 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2875 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2879 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2880 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2883 /* Crashes on some Win9x */
2884 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2885 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2886 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2887 emptyHashParam, sizeof(emptyHashParam));
2890 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2891 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2892 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2894 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2896 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2897 hashParam, sizeof(hashParam));
2898 /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2899 * even though there's only one hash.
2901 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2902 ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2903 "CryptMsgGetParam failed: %08x\n", GetLastError());
2905 buf = CryptMemAlloc(size);
2910 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2911 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2912 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2915 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2916 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2917 value = CMSG_HASHED_DATA_V0;
2918 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2922 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2923 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2924 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2925 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2927 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2928 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2929 size = sizeof(value);
2931 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2932 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2933 ok(value == 1, "Expected 1 signer, got %d\n", value);
2935 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2936 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2937 "CryptMsgGetParam failed: %08x\n", GetLastError());
2939 buf = CryptMemAlloc(size);
2944 CMSG_SIGNER_INFO signer = { 0 };
2946 signer.dwVersion = 1;
2947 signer.Issuer.cbData = sizeof(encodedCommonName);
2948 signer.Issuer.pbData = encodedCommonName;
2949 signer.SerialNumber.cbData = sizeof(serialNum);
2950 signer.SerialNumber.pbData = serialNum;
2951 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2952 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2953 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2956 /* Getting the CMS signer info of a PKCS7 message is possible. */
2958 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2959 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2960 "CryptMsgGetParam failed: %08x\n", GetLastError());
2962 buf = CryptMemAlloc(size);
2967 CMSG_CMS_SIGNER_INFO signer = { 0 };
2969 signer.dwVersion = 1;
2970 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2971 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2972 sizeof(encodedCommonName);
2973 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2974 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2976 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2977 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2978 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2979 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2982 /* index is ignored when getting signer count */
2983 size = sizeof(value);
2984 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2985 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2986 ok(value == 1, "Expected 1 signer, got %d\n", value);
2987 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2988 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2989 ok(value == 0, "Expected 0 certs, got %d\n", value);
2990 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2991 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2992 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2994 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2996 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2997 sizeof(signedWithCertAndCrlBareContent), TRUE);
2998 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2999 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
3000 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3001 ok(value == 1, "Expected 1 cert, got %d\n", value);
3002 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
3003 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
3004 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3005 ok(value == 1, "Expected 1 CRL, got %d\n", value);
3006 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
3007 check_param("signed with cert and CRL computed hash", msg,
3008 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
3009 sizeof(signedWithCertAndCrlComputedHash));
3012 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3013 ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
3014 sizeof(signedKeyIdEmptyContent), TRUE);
3015 if (!ret && GetLastError() == OSS_DATA_ERROR)
3018 win_skip("Subsequent tests crash on some Win9x\n");
3021 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3022 size = sizeof(value);
3023 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
3024 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3025 ok(value == 1, "Expected 1 signer, got %d\n", value);
3026 /* Getting the regular (non-CMS) signer info from a CMS message is also
3030 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
3031 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3033 buf = CryptMemAlloc(size);
3038 CMSG_SIGNER_INFO signer;
3041 /* and here's the little oddity: for a CMS message using the key id
3042 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
3043 * a signer with a zero (not empty) serial number, and whose issuer is
3044 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
3045 * and value of the key id.
3047 signer.dwVersion = CMSG_SIGNED_DATA_V3;
3048 signer.Issuer.cbData = sizeof(keyIdIssuer);
3049 signer.Issuer.pbData = keyIdIssuer;
3050 signer.SerialNumber.cbData = 1;
3051 signer.SerialNumber.pbData = &zero;
3052 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
3053 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
3057 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
3058 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3060 buf = CryptMemAlloc(size);
3065 CMSG_CMS_SIGNER_INFO signer = { 0 };
3067 signer.dwVersion = CMSG_SIGNED_DATA_V3;
3068 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
3069 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
3070 U(signer.SignerId).KeyId.pbData = serialNum;
3071 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3072 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
3073 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
3078 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3080 CryptMsgUpdate(msg, envelopedEmptyBareContent,
3081 sizeof(envelopedEmptyBareContent), TRUE);
3083 check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL,
3087 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3088 CryptMsgUpdate(msg, envelopedEmptyContent, sizeof(envelopedEmptyContent),
3091 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0);
3094 CryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL,
3095 CRYPT_VERIFYCONTEXT);
3096 SetLastError(0xdeadbeef);
3097 ret = CryptImportKey(hCryptProv, publicPrivateKeyPair,
3098 sizeof(publicPrivateKeyPair), 0, 0, &key);
3099 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
3101 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3102 CryptMsgUpdate(msg, envelopedMessage, sizeof(envelopedMessage), TRUE);
3104 check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM,
3105 envelopedMessage + sizeof(envelopedMessage) - 4, 4);
3106 decryptPara.hCryptProv = hCryptProv;
3107 SetLastError(0xdeadbeef);
3108 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3110 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3111 decryptPara.hCryptProv = 0;
3112 SetLastError(0xdeadbeef);
3113 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3115 ok(!ret && GetLastError() == CRYPT_E_ALREADY_DECRYPTED,
3116 "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError());
3118 check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData,
3122 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3124 CryptMsgUpdate(msg, envelopedBareMessage, sizeof(envelopedBareMessage),
3127 check_param("enveloped bare message before decrypting", msg,
3128 CMSG_CONTENT_PARAM, envelopedBareMessage +
3129 sizeof(envelopedBareMessage) - 4, 4);
3130 decryptPara.hCryptProv = hCryptProv;
3131 SetLastError(0xdeadbeef);
3132 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3134 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3136 check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData,
3140 CryptDestroyKey(key);
3141 CryptReleaseContext(hCryptProv, 0);
3143 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3144 CryptMsgUpdate(msg, envelopedMessageWith3Recps,
3145 sizeof(envelopedMessageWith3Recps), TRUE);
3148 check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM,
3149 (const BYTE *)&value, sizeof(value));
3151 SetLastError(0xdeadbeef);
3152 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 3, NULL, &size);
3154 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3155 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3157 SetLastError(0xdeadbeef);
3158 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, NULL, &size);
3160 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3162 ok(size >= 142, "unexpected size: %u\n", size);
3164 buf = CryptMemAlloc(size);
3169 CERT_INFO *certInfo = (CERT_INFO *)buf;
3171 SetLastError(0xdeadbeef);
3172 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, buf, &size);
3174 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3176 ok(certInfo->SerialNumber.cbData == sizeof(serialNumber),
3177 "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData);
3179 ok(!memcmp(certInfo->SerialNumber.pbData, serialNumber,
3180 sizeof(serialNumber)), "unexpected serial number\n");
3182 ok(certInfo->Issuer.cbData == sizeof(issuer),
3183 "unexpected issuer size: %u\n", certInfo->Issuer.cbData);
3185 ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)),
3186 "unexpected issuer\n");
3192 static void test_decode_msg(void)
3194 test_decode_msg_update();
3195 test_decode_msg_get_param();
3198 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
3199 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
3200 static BYTE encodedPubKey[] = {
3201 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
3202 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
3204 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
3205 static BYTE mod_encoded[] = {
3206 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
3209 static void test_msg_control(void)
3211 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3215 CERT_INFO certInfo = { 0 };
3216 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
3217 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
3218 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
3221 ret = CryptMsgControl(NULL, 0, 0, NULL);
3224 /* Data encode messages don't allow any sort of control.. */
3225 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
3227 /* either with no prior update.. */
3228 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3230 SetLastError(0xdeadbeef);
3231 ret = CryptMsgControl(msg, 0, i, NULL);
3232 ok(!ret && GetLastError() == E_INVALIDARG,
3233 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3235 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3236 /* or after an update. */
3237 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3239 SetLastError(0xdeadbeef);
3240 ret = CryptMsgControl(msg, 0, i, NULL);
3241 ok(!ret && GetLastError() == E_INVALIDARG,
3242 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3246 /* Hash encode messages don't allow any sort of control.. */
3247 hashInfo.cbSize = sizeof(hashInfo);
3248 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
3249 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
3251 /* either with no prior update.. */
3252 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3254 SetLastError(0xdeadbeef);
3255 ret = CryptMsgControl(msg, 0, i, NULL);
3256 ok(!ret && GetLastError() == E_INVALIDARG,
3257 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3259 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3260 /* or after an update. */
3261 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3263 SetLastError(0xdeadbeef);
3264 ret = CryptMsgControl(msg, 0, i, NULL);
3265 ok(!ret && GetLastError() == E_INVALIDARG,
3266 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3270 /* Signed encode messages likewise don't allow any sort of control.. */
3271 signInfo.cbSize = sizeof(signInfo);
3272 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
3274 /* either before 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());
3282 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3283 /* or after an update. */
3284 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3286 SetLastError(0xdeadbeef);
3287 ret = CryptMsgControl(msg, 0, i, NULL);
3288 ok(!ret && GetLastError() == E_INVALIDARG,
3289 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3293 /* Decode messages behave a bit differently. */
3294 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3295 /* Bad control type */
3296 SetLastError(0xdeadbeef);
3297 ret = CryptMsgControl(msg, 0, 0, NULL);
3298 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3299 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3300 SetLastError(0xdeadbeef);
3301 ret = CryptMsgControl(msg, 1, 0, NULL);
3302 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3303 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3304 /* Can't verify the hash of an indeterminate-type message */
3305 SetLastError(0xdeadbeef);
3306 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3307 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3308 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3310 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
3312 /* Can't decrypt an indeterminate-type message */
3313 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3314 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3315 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3320 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3322 /* Can't verify the hash of an empty message */
3323 SetLastError(0xdeadbeef);
3324 /* Crashes on some Win9x */
3325 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3327 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3328 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3330 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3332 /* Can't verify the signature of a hash message */
3333 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3334 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3335 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3336 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
3338 /* Oddly enough, this fails, crashes on some Win9x */
3339 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3340 ok(!ret, "Expected failure\n");
3343 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3345 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
3346 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3347 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3348 /* Can't decrypt an indeterminate-type message */
3349 SetLastError(0xdeadbeef);
3350 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3351 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3352 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3355 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3357 /* Can't verify the hash of a detached message before it's been updated. */
3358 SetLastError(0xdeadbeef);
3359 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3360 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3361 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3362 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3364 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3365 /* Still can't verify the hash of a detached message with the content
3366 * of the detached hash given..
3368 SetLastError(0xdeadbeef);
3369 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3370 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
3371 "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
3372 /* and giving the content of the message after attempting to verify the
3375 SetLastError(0xdeadbeef);
3376 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3379 (GetLastError() == NTE_BAD_HASH_STATE ||
3380 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3381 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
3382 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3383 "got %08x\n", GetLastError());
3386 /* Finally, verifying the hash of a detached message in the correct order:
3387 * 1. Update with the detached hash message
3388 * 2. Update with the content of the message
3389 * 3. Verifying the hash of the message
3392 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3394 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3396 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3397 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3398 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3399 SetLastError(0xdeadbeef);
3400 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3401 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3404 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3406 /* Can't verify the hash of a signed message */
3407 SetLastError(0xdeadbeef);
3408 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3409 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3410 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3411 /* Can't decrypt a signed message */
3412 SetLastError(0xdeadbeef);
3413 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3414 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3415 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3417 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3418 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3420 CryptMsgUpdate(msg, signedWithCertBareContent,
3421 sizeof(signedWithCertBareContent), TRUE);
3422 /* With an empty cert info, the signer can't be found in the message (and
3423 * the signature can't be verified.
3425 SetLastError(0xdeadbeef);
3426 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3427 ok(!ret && (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND ||
3428 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3429 "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n",
3431 /* The cert info is expected to have an issuer, serial number, and public
3434 certInfo.SerialNumber.cbData = sizeof(serialNum);
3435 certInfo.SerialNumber.pbData = serialNum;
3436 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3437 certInfo.Issuer.pbData = encodedCommonName;
3438 SetLastError(0xdeadbeef);
3439 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3440 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3441 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3442 "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError());
3444 /* This cert has a public key, but it's not in a usable form */
3445 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3447 ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
3448 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
3451 /* Crashes on some Win9x */
3452 /* Again, cert info needs to have a public key set */
3453 SetLastError(0xdeadbeef);
3454 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3456 (GetLastError() == CRYPT_E_ASN1_EOD ||
3457 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3458 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3459 /* The public key is supposed to be in encoded form.. */
3460 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3461 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3462 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
3463 SetLastError(0xdeadbeef);
3464 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3466 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3467 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3468 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3469 /* but not as a X509_PUBLIC_KEY_INFO.. */
3470 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3471 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
3472 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
3473 SetLastError(0xdeadbeef);
3474 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3476 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3477 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3478 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3479 /* This decodes successfully, but it doesn't match any key in the message */
3480 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
3481 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
3482 SetLastError(0xdeadbeef);
3483 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3484 /* In Wine's rsaenh, this fails to decode because the key length is too
3485 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
3490 (GetLastError() == NTE_BAD_SIGNATURE ||
3491 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3492 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3495 /* A message with no data doesn't have a valid signature */
3496 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3497 ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
3498 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
3501 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3502 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
3503 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
3504 SetLastError(0xdeadbeef);
3505 /* Crashes on some Win9x */
3506 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3508 (GetLastError() == NTE_BAD_SIGNATURE ||
3509 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3510 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3513 /* Finally, this succeeds */
3514 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3515 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3516 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3517 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3518 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3519 "CryptMsgControl failed: %08x\n", GetLastError());
3522 /* Test verifying signature of a detached signed message */
3523 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3525 ret = CryptMsgUpdate(msg, detachedSignedContent,
3526 sizeof(detachedSignedContent), TRUE);
3527 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3528 /* Can't verify the sig without having updated the data */
3529 SetLastError(0xdeadbeef);
3530 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3531 ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
3532 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3533 "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n",
3535 /* Now that the signature's been checked, can't do the final update */
3536 SetLastError(0xdeadbeef);
3537 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3540 (GetLastError() == NTE_BAD_HASH_STATE ||
3541 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3542 GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */
3543 broken(ret), /* Win9x */
3544 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3545 "got %08x\n", GetLastError());
3547 /* Updating with the detached portion of the message and the data of the
3548 * the message allows the sig to be verified.
3550 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3552 ret = CryptMsgUpdate(msg, detachedSignedContent,
3553 sizeof(detachedSignedContent), TRUE);
3554 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3555 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3556 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3557 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3558 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3559 "CryptMsgControl failed: %08x\n", GetLastError());
3562 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3564 decryptPara.cbSize = 0;
3565 SetLastError(0xdeadbeef);
3566 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3568 ok(!ret && GetLastError() == E_INVALIDARG,
3569 "expected E_INVALIDARG, got %08x\n", GetLastError());
3570 decryptPara.cbSize = sizeof(decryptPara);
3573 SetLastError(0xdeadbeef);
3574 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3575 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3576 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3578 SetLastError(0xdeadbeef);
3579 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
3580 sizeof(envelopedEmptyBareContent), TRUE);
3581 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3582 SetLastError(0xdeadbeef);
3583 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3585 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3586 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3589 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3591 SetLastError(0xdeadbeef);
3592 ret = CryptMsgUpdate(msg, envelopedBareMessage,
3593 sizeof(envelopedBareMessage), TRUE);
3594 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3595 SetLastError(0xdeadbeef);
3596 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3598 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
3599 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
3603 /* win9x has much less parameter checks and will crash on many tests
3604 * this code is from test_signed_msg_update()
3606 static BOOL detect_nt(void)
3609 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
3610 CERT_INFO certInfo = { 0 };
3612 if (!pCryptAcquireContextW)
3615 certInfo.SerialNumber.cbData = sizeof(serialNum);
3616 certInfo.SerialNumber.pbData = serialNum;
3617 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3618 certInfo.Issuer.pbData = encodedCommonName;
3619 signer.pCertInfo = &certInfo;
3620 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3622 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3623 PROV_RSA_FULL, CRYPT_NEWKEYSET);
3624 if (!ret && GetLastError() == NTE_EXISTS) {
3625 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3629 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
3632 CryptReleaseContext(signer.hCryptProv, 0);
3633 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
3634 CRYPT_DELETEKEYSET);
3639 static void test_msg_get_and_verify_signer(void)
3643 PCCERT_CONTEXT signer;
3650 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
3651 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3654 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3655 /* An empty message has no signer */
3656 SetLastError(0xdeadbeef);
3657 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3658 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3659 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3660 /* The signer is cleared on error */
3661 signer = (PCCERT_CONTEXT)0xdeadbeef;
3662 SetLastError(0xdeadbeef);
3663 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3664 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3665 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3666 ok(!signer, "expected signer to be NULL\n");
3667 /* The signer index is also cleared on error */
3668 signerIndex = 0xdeadbeef;
3669 SetLastError(0xdeadbeef);
3670 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3671 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3672 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3673 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
3674 /* An unsigned message (msgData isn't a signed message at all)
3675 * likewise has no signer.
3677 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3678 SetLastError(0xdeadbeef);
3679 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3680 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3681 "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 created with no signer cert likewise has no signer */
3686 ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
3689 /* Crashes on most Win9x */
3690 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3691 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3692 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3696 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3697 /* A signed message succeeds, .. */
3698 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3699 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3700 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3701 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3702 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3703 /* the signer index can be retrieved, .. */
3704 signerIndex = 0xdeadbeef;
3705 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3706 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3707 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3709 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
3710 /* as can the signer cert. */
3711 signer = (PCCERT_CONTEXT)0xdeadbeef;
3712 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3713 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3714 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3716 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3717 "expected a valid signer\n");
3718 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3719 CertFreeCertificateContext(signer);
3720 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3722 signerIndex = 0xdeadbeef;
3723 SetLastError(0xdeadbeef);
3724 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3725 NULL, &signerIndex);
3726 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3727 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3728 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3729 * message signer not to be found.
3731 SetLastError(0xdeadbeef);
3732 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3734 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3735 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3736 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3737 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3738 * the message signer not to be found.
3740 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3741 CERT_STORE_CREATE_NEW_FLAG, NULL);
3742 SetLastError(0xdeadbeef);
3743 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3745 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3746 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3747 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3748 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3749 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3750 CERT_STORE_ADD_ALWAYS, NULL);
3751 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win98 */),
3752 "CertAddEncodedCertificateToStore failed: 0x%08x\n", GetLastError());
3753 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3754 * the signer succeeds.
3756 SetLastError(0xdeadbeef);
3757 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3759 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3760 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3761 CertCloseStore(store, 0);
3767 init_function_pointers();
3768 have_nt = detect_nt();
3770 win_skip("Win9x crashes on some parameter checks\n");
3772 /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
3773 if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
3775 win_skip("Some tests will crash on older crypt32 implementations\n");
3779 /* Basic parameter checking tests */
3780 test_msg_open_to_encode();
3781 test_msg_open_to_decode();
3782 test_msg_get_param();
3786 /* Message-type specific tests */
3790 test_enveloped_msg();
3793 test_msg_get_and_verify_signer();