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);
2046 ok(!msg && GetLastError() == E_INVALIDARG,
2047 "expected E_INVALIDARG, got %08x\n", GetLastError());
2049 envelopedInfo.cbSize = sizeof(envelopedInfo);
2050 SetLastError(0xdeadbeef);
2051 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2052 &envelopedInfo, NULL, NULL);
2054 (GetLastError() == CRYPT_E_UNKNOWN_ALGO ||
2055 GetLastError() == E_INVALIDARG), /* Win9x */
2056 "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", GetLastError());
2058 envelopedInfo.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4;
2059 SetLastError(0xdeadbeef);
2060 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2061 &envelopedInfo, NULL, NULL);
2063 broken(!msg), /* Win9x */
2064 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2067 envelopedInfo.cRecipients = 1;
2070 SetLastError(0xdeadbeef);
2071 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2072 &envelopedInfo, NULL, NULL);
2073 ok(!msg && GetLastError() == E_INVALIDARG,
2074 "expected E_INVALIDARG, got %08x\n", GetLastError());
2077 context = CertCreateCertificateContext(X509_ASN_ENCODING,
2078 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
2081 envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo;
2082 SetLastError(0xdeadbeef);
2083 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2084 &envelopedInfo, NULL, NULL);
2085 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2087 SetLastError(0xdeadbeef);
2088 ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL,
2089 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
2090 ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
2091 SetLastError(0xdeadbeef);
2092 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2093 &envelopedInfo, NULL, NULL);
2094 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2096 CryptReleaseContext(envelopedInfo.hCryptProv, 0);
2097 CertFreeCertificateContext(context);
2100 win_skip("failed to create certificate context, skipping tests\n");
2103 static void test_enveloped_msg_update(void)
2107 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2108 { oid_rsa_rc4, { 0, NULL } }, NULL };
2109 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
2111 SetLastError(0xdeadbeef);
2112 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2113 &envelopedInfo, NULL, NULL);
2115 broken(!msg), /* Win9x */
2116 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2119 SetLastError(0xdeadbeef);
2120 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2121 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2122 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2123 SetLastError(0xdeadbeef);
2124 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2125 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2126 SetLastError(0xdeadbeef);
2127 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2128 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2129 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2132 SetLastError(0xdeadbeef);
2133 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2134 &envelopedInfo, NULL, NULL);
2136 broken(!msg), /* Win9x */
2137 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2140 SetLastError(0xdeadbeef);
2141 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2142 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2143 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2144 SetLastError(0xdeadbeef);
2145 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2147 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2148 "CryptMsgUpdate failed: %08x\n", GetLastError());
2149 SetLastError(0xdeadbeef);
2150 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2151 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2152 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2155 SetLastError(0xdeadbeef);
2156 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2157 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2159 broken(!msg), /* Win9x */
2160 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2163 SetLastError(0xdeadbeef);
2164 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2165 ok(!ret && GetLastError() == E_INVALIDARG,
2166 "expected E_INVALIDARG, got %08x\n", GetLastError());
2167 SetLastError(0xdeadbeef);
2168 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2169 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2172 SetLastError(0xdeadbeef);
2173 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2174 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2176 broken(!msg), /* Win9x */
2177 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2180 SetLastError(0xdeadbeef);
2181 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2182 ok(!ret && GetLastError() == E_INVALIDARG,
2183 "expected E_INVALIDARG, got %08x\n", GetLastError());
2184 SetLastError(0xdeadbeef);
2185 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2187 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2188 "CryptMsgUpdate failed: %08x\n", GetLastError());
2191 SetLastError(0xdeadbeef);
2192 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2193 &envelopedInfo, NULL, &streamInfo);
2195 broken(!msg), /* Win9x */
2196 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2199 SetLastError(0xdeadbeef);
2200 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2201 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2202 SetLastError(0xdeadbeef);
2203 ret = CryptMsgUpdate(msg, NULL, 0, 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);
2211 broken(!msg), /* Win9x */
2212 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2215 SetLastError(0xdeadbeef);
2216 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2217 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2218 SetLastError(0xdeadbeef);
2219 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2221 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2222 "CryptMsgUpdate failed: %08x\n", GetLastError());
2227 static const BYTE envelopedEmptyBareContent[] = {
2228 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2229 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2230 0x03,0x04,0x05,0x00,0x80,0x00 };
2231 static const BYTE envelopedEmptyContent[] = {
2232 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24,
2233 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2234 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2235 0x03,0x04,0x05,0x00,0x80,0x00 };
2237 static void test_enveloped_msg_encoding(void)
2240 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2241 { oid_rsa_rc4, { 0, NULL } }, NULL };
2243 SetLastError(0xdeadbeef);
2244 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2245 &envelopedInfo, NULL, NULL);
2247 broken(!msg), /* Win9x */
2248 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2251 check_param("enveloped empty bare content", msg,
2252 CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent,
2253 sizeof(envelopedEmptyBareContent));
2254 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
2255 envelopedEmptyContent, sizeof(envelopedEmptyContent));
2260 static void test_enveloped_msg(void)
2262 test_enveloped_msg_open();
2263 test_enveloped_msg_update();
2264 test_enveloped_msg_encoding();
2267 static CRYPT_DATA_BLOB b4 = { 0, NULL };
2268 static const struct update_accum a4 = { 1, &b4 };
2270 static const BYTE bogusOIDContent[] = {
2271 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2273 static const BYTE bogusHashContent[] = {
2274 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2275 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2276 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2277 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2278 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2279 static const BYTE envelopedBareContentWithoutData[] = {
2280 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2281 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2282 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2283 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2284 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b,
2285 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f,
2286 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94,
2287 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72,
2288 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18,
2289 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3,
2290 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6,
2291 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49,
2292 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e,
2293 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2294 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 };
2296 static void test_decode_msg_update(void)
2300 CMSG_STREAM_INFO streamInfo = { 0 };
2302 struct update_accum accum = { 0, NULL };
2304 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2305 /* Update with a full message in a final update */
2306 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2307 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2308 /* Can't update after a final update */
2309 SetLastError(0xdeadbeef);
2310 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2311 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2312 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2315 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2316 /* Can't send a non-final update without streaming */
2317 SetLastError(0xdeadbeef);
2318 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2320 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2321 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2322 /* A subsequent final update succeeds */
2323 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2324 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2329 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2330 /* Updating a message that has a NULL stream callback fails */
2331 SetLastError(0xdeadbeef);
2332 /* Crashes on some Win9x */
2333 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2336 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2337 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2338 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2340 /* Changing the callback pointer after the fact yields the same error (so
2341 * the message must copy the stream info, not just store a pointer to it)
2343 streamInfo.pfnStreamOutput = nop_stream_output;
2344 SetLastError(0xdeadbeef);
2345 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2348 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2349 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2350 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2355 /* Empty non-final updates are allowed when streaming.. */
2356 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2357 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2358 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2359 /* but final updates aren't when not enough data has been received. */
2360 SetLastError(0xdeadbeef);
2361 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2363 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2364 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2367 /* Updating the message byte by byte is legal */
2368 streamInfo.pfnStreamOutput = accumulating_stream_output;
2369 streamInfo.pvArg = &accum;
2370 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2371 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2372 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2373 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2374 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2375 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2378 check_updates("byte-by-byte empty content", &a4, &accum);
2379 free_updates(&accum);
2381 /* Decoding bogus content fails in non-streaming mode.. */
2382 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2383 SetLastError(0xdeadbeef);
2384 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2385 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2386 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2387 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2390 /* and as the final update in streaming mode.. */
2391 streamInfo.pfnStreamOutput = nop_stream_output;
2392 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2393 SetLastError(0xdeadbeef);
2394 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2395 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2396 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2397 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2400 /* and even as a non-final update in streaming mode. */
2401 streamInfo.pfnStreamOutput = nop_stream_output;
2402 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2403 SetLastError(0xdeadbeef);
2404 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
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",
2412 /* An empty message can be opened with undetermined type.. */
2413 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2414 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2416 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2418 /* but decoding it as an explicitly typed message fails. */
2419 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2421 SetLastError(0xdeadbeef);
2422 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2424 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2425 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2426 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2429 /* On the other hand, decoding the bare content of an empty message fails
2430 * with unspecified type..
2432 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2433 SetLastError(0xdeadbeef);
2434 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2435 sizeof(dataEmptyBareContent), TRUE);
2436 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2437 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2438 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2441 /* but succeeds with explicit type. */
2442 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2444 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2445 sizeof(dataEmptyBareContent), TRUE);
2446 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2449 /* Decoding valid content with an unsupported OID fails */
2450 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2451 SetLastError(0xdeadbeef);
2452 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2453 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2454 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2457 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2458 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2459 SetLastError(0xdeadbeef);
2460 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2461 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2462 "CryptMsgUpdate failed: %08x\n", GetLastError());
2464 /* while with specified type it fails. */
2465 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2467 SetLastError(0xdeadbeef);
2468 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2469 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2470 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2471 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2472 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2475 /* On the other hand, decoding the bare content of an empty hash message
2476 * fails with unspecified type..
2478 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2479 SetLastError(0xdeadbeef);
2480 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2481 sizeof(hashEmptyBareContent), TRUE);
2482 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2483 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2484 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2485 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2488 /* but succeeds with explicit type. */
2489 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2491 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2492 sizeof(hashEmptyBareContent), TRUE);
2493 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2494 "CryptMsgUpdate failed: %x\n", GetLastError());
2497 /* And again, opening a (non-empty) hash message with unspecified type
2500 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2501 SetLastError(0xdeadbeef);
2502 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2503 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2505 /* while with specified type it fails.. */
2506 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2508 SetLastError(0xdeadbeef);
2509 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2510 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2511 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2512 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2513 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2516 /* and decoding the bare content of a non-empty hash message fails with
2517 * unspecified type..
2519 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2520 SetLastError(0xdeadbeef);
2521 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2522 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2523 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2524 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2525 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2528 /* but succeeds with explicit type. */
2529 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2531 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2532 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2535 /* Opening a (non-empty) hash message with unspecified type and a bogus
2536 * hash value succeeds..
2538 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2539 SetLastError(0xdeadbeef);
2540 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2541 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2544 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2545 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2546 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2548 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2549 SetLastError(0xdeadbeef);
2550 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2551 sizeof(signedWithCertAndCrlBareContent), TRUE);
2552 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2553 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2554 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2557 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2559 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2560 sizeof(signedWithCertAndCrlBareContent), TRUE);
2561 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2564 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2566 /* The first update succeeds.. */
2567 ret = CryptMsgUpdate(msg, detachedSignedContent,
2568 sizeof(detachedSignedContent), TRUE);
2569 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2570 /* as does a second (probably to update the detached portion).. */
2571 ret = CryptMsgUpdate(msg, detachedSignedContent,
2572 sizeof(detachedSignedContent), TRUE);
2573 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2574 /* while a third fails. */
2575 ret = CryptMsgUpdate(msg, detachedSignedContent,
2576 sizeof(detachedSignedContent), TRUE);
2577 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2578 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2581 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2582 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2583 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2584 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2585 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2586 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2587 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2588 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2589 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2591 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2592 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2593 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2596 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2598 SetLastError(0xdeadbeef);
2599 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2600 sizeof(envelopedEmptyBareContent), TRUE);
2601 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2604 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2606 SetLastError(0xdeadbeef);
2607 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2608 sizeof(envelopedEmptyContent), TRUE);
2611 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2612 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2613 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2616 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2617 SetLastError(0xdeadbeef);
2618 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2619 sizeof(envelopedEmptyBareContent), TRUE);
2621 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2622 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2623 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2626 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2627 SetLastError(0xdeadbeef);
2628 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2629 sizeof(envelopedEmptyContent), TRUE);
2630 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2633 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2635 SetLastError(0xdeadbeef);
2636 ret = CryptMsgUpdate(msg, envelopedBareContentWithoutData,
2637 sizeof(envelopedBareContentWithoutData), TRUE);
2638 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2642 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2643 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2645 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2646 const CMSG_SIGNER_INFO *expected)
2648 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2649 expected->dwVersion, got->dwVersion);
2650 ok(got->Issuer.cbData == expected->Issuer.cbData,
2651 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2652 got->Issuer.cbData);
2653 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2654 "Unexpected issuer\n");
2655 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2656 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2657 got->SerialNumber.cbData);
2658 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2659 got->SerialNumber.cbData), "Unexpected serial number\n");
2660 /* FIXME: check more things */
2663 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2664 const CMSG_CMS_SIGNER_INFO *expected)
2666 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2667 expected->dwVersion, got->dwVersion);
2668 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2669 "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2670 got->SignerId.dwIdChoice);
2671 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2673 if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2675 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2676 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2677 "Expected issuer size %d, got %d\n",
2678 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2679 U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2680 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2681 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2682 U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2683 "Unexpected issuer\n");
2684 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2685 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2686 "Expected serial number size %d, got %d\n",
2687 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2688 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2689 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2690 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2691 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2692 "Unexpected serial number\n");
2696 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2697 "expected key id size %d, got %d\n",
2698 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2699 ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2700 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2701 "unexpected key id\n");
2704 /* FIXME: check more things */
2707 static const BYTE signedWithCertAndCrlComputedHash[] = {
2708 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2710 static BYTE keyIdIssuer[] = {
2711 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2712 0x0a,0x07,0x01,0x04,0x01,0x01 };
2713 static const BYTE publicPrivateKeyPair[] = {
2714 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00,
2715 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b,
2716 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50,
2717 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54,
2718 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39,
2719 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7,
2720 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48,
2721 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17,
2722 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54,
2723 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33,
2724 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52,
2725 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e,
2726 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61,
2727 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb,
2728 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02,
2729 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90,
2730 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e,
2731 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce,
2732 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14,
2733 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5,
2734 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5,
2735 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94,
2736 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68,
2737 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71,
2738 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25,
2739 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc,
2740 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a,
2741 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64,
2742 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77,
2743 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68,
2744 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab,
2745 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9,
2746 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed,
2747 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01,
2748 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e,
2749 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71,
2750 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0,
2751 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87,
2752 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b,
2753 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e };
2754 static const BYTE envelopedMessage[] = {
2755 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,
2756 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,
2757 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,
2758 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,
2759 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
2760 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65,
2761 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae,
2762 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1,
2763 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51,
2764 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf,
2765 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b,
2766 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e,
2767 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e,
2768 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70,
2769 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,
2770 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,
2771 0x04,0x5f,0x80,0xf2,0x17 };
2772 static const BYTE envelopedBareMessage[] = {
2773 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2774 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2775 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2776 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2777 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d,
2778 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d,
2779 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5,
2780 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e,
2781 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2,
2782 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4,
2783 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70,
2784 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c,
2785 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55,
2786 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2787 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c,
2789 static const BYTE envelopedMessageWith3Recps[] = {
2790 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,
2791 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e,
2792 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,
2793 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,
2794 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,
2795 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e,
2796 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba,
2797 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f,
2798 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5,
2799 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21,
2800 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae,
2801 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0,
2802 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96,
2803 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae,
2804 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,
2805 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,
2806 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6,
2807 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
2808 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf,
2809 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9,
2810 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3,
2811 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02,
2812 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70,
2813 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3,
2814 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74,
2815 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94,
2816 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7,
2817 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,
2818 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,
2819 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
2820 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98,
2821 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5,
2822 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9,
2823 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3,
2824 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8,
2825 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac,
2826 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc,
2827 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5,
2828 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1,
2829 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
2830 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,
2831 0x80,0x04,0x4e,0x99,0x9d,0x4c };
2832 static const BYTE serialNumber[] = {
2833 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2,
2835 static const BYTE issuer[] = {
2836 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 };
2838 static void test_decode_msg_get_param(void)
2841 HCRYPTPROV hCryptProv;
2844 DWORD size = 0, value;
2846 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2848 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2849 SetLastError(0xdeadbeef);
2850 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2851 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2852 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2853 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2854 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2858 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2859 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2862 /* Crashes on some Win9x */
2863 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2864 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2865 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2866 emptyHashParam, sizeof(emptyHashParam));
2869 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2870 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2871 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2873 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2875 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2876 hashParam, sizeof(hashParam));
2877 /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2878 * even though there's only one hash.
2880 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2881 ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2882 "CryptMsgGetParam failed: %08x\n", GetLastError());
2884 buf = CryptMemAlloc(size);
2889 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2890 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2891 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2894 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2895 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2896 value = CMSG_HASHED_DATA_V0;
2897 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2901 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2902 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2903 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2904 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2906 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2907 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2908 size = sizeof(value);
2910 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2911 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2912 ok(value == 1, "Expected 1 signer, got %d\n", value);
2914 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2915 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2916 "CryptMsgGetParam failed: %08x\n", GetLastError());
2918 buf = CryptMemAlloc(size);
2923 CMSG_SIGNER_INFO signer = { 0 };
2925 signer.dwVersion = 1;
2926 signer.Issuer.cbData = sizeof(encodedCommonName);
2927 signer.Issuer.pbData = encodedCommonName;
2928 signer.SerialNumber.cbData = sizeof(serialNum);
2929 signer.SerialNumber.pbData = serialNum;
2930 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2931 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2932 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2935 /* Getting the CMS signer info of a PKCS7 message is possible. */
2937 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2938 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2939 "CryptMsgGetParam failed: %08x\n", GetLastError());
2941 buf = CryptMemAlloc(size);
2946 CMSG_CMS_SIGNER_INFO signer = { 0 };
2948 signer.dwVersion = 1;
2949 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2950 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2951 sizeof(encodedCommonName);
2952 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2953 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2955 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2956 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2957 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2958 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2961 /* index is ignored when getting signer count */
2962 size = sizeof(value);
2963 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2964 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2965 ok(value == 1, "Expected 1 signer, got %d\n", value);
2966 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2967 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2968 ok(value == 0, "Expected 0 certs, got %d\n", value);
2969 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2970 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2971 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2973 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2975 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2976 sizeof(signedWithCertAndCrlBareContent), TRUE);
2977 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2978 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2979 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2980 ok(value == 1, "Expected 1 cert, got %d\n", value);
2981 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2982 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2983 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2984 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2985 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2986 check_param("signed with cert and CRL computed hash", msg,
2987 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2988 sizeof(signedWithCertAndCrlComputedHash));
2991 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2992 ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
2993 sizeof(signedKeyIdEmptyContent), TRUE);
2994 if (!ret && GetLastError() == OSS_DATA_ERROR)
2997 win_skip("Subsequent tests crash on some Win9x\n");
3000 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3001 size = sizeof(value);
3002 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
3003 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3004 ok(value == 1, "Expected 1 signer, got %d\n", value);
3005 /* Getting the regular (non-CMS) signer info from a CMS message is also
3009 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
3010 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3012 buf = CryptMemAlloc(size);
3017 CMSG_SIGNER_INFO signer;
3020 /* and here's the little oddity: for a CMS message using the key id
3021 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
3022 * a signer with a zero (not empty) serial number, and whose issuer is
3023 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
3024 * and value of the key id.
3026 signer.dwVersion = CMSG_SIGNED_DATA_V3;
3027 signer.Issuer.cbData = sizeof(keyIdIssuer);
3028 signer.Issuer.pbData = keyIdIssuer;
3029 signer.SerialNumber.cbData = 1;
3030 signer.SerialNumber.pbData = &zero;
3031 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
3032 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
3036 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
3037 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3039 buf = CryptMemAlloc(size);
3044 CMSG_CMS_SIGNER_INFO signer = { 0 };
3046 signer.dwVersion = CMSG_SIGNED_DATA_V3;
3047 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
3048 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
3049 U(signer.SignerId).KeyId.pbData = serialNum;
3050 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3051 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
3052 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
3057 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3059 CryptMsgUpdate(msg, envelopedEmptyBareContent,
3060 sizeof(envelopedEmptyBareContent), TRUE);
3062 check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL,
3066 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3067 CryptMsgUpdate(msg, envelopedEmptyContent, sizeof(envelopedEmptyContent),
3070 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0);
3073 pCryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL,
3074 CRYPT_VERIFYCONTEXT);
3075 SetLastError(0xdeadbeef);
3076 ret = CryptImportKey(hCryptProv, publicPrivateKeyPair,
3077 sizeof(publicPrivateKeyPair), 0, 0, &key);
3079 broken(!ret && GetLastError() == NTE_PERM), /* WinME and some NT4 */
3080 "CryptImportKey failed: %08x\n", GetLastError());
3082 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3083 CryptMsgUpdate(msg, envelopedMessage, sizeof(envelopedMessage), TRUE);
3085 check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM,
3086 envelopedMessage + sizeof(envelopedMessage) - 4, 4);
3089 decryptPara.hCryptProv = hCryptProv;
3090 SetLastError(0xdeadbeef);
3091 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3093 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3094 decryptPara.hCryptProv = 0;
3095 SetLastError(0xdeadbeef);
3096 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3098 ok(!ret && GetLastError() == CRYPT_E_ALREADY_DECRYPTED,
3099 "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError());
3101 check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData,
3105 win_skip("failed to import a key, skipping tests\n");
3108 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3110 CryptMsgUpdate(msg, envelopedBareMessage, sizeof(envelopedBareMessage),
3113 check_param("enveloped bare message before decrypting", msg,
3114 CMSG_CONTENT_PARAM, envelopedBareMessage +
3115 sizeof(envelopedBareMessage) - 4, 4);
3118 decryptPara.hCryptProv = hCryptProv;
3119 SetLastError(0xdeadbeef);
3120 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3122 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3124 check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData,
3128 win_skip("failed to import a key, skipping tests\n");
3132 CryptDestroyKey(key);
3133 CryptReleaseContext(hCryptProv, 0);
3135 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3136 CryptMsgUpdate(msg, envelopedMessageWith3Recps,
3137 sizeof(envelopedMessageWith3Recps), TRUE);
3140 check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM,
3141 (const BYTE *)&value, sizeof(value));
3143 SetLastError(0xdeadbeef);
3144 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 3, NULL, &size);
3146 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3147 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3149 SetLastError(0xdeadbeef);
3150 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, NULL, &size);
3152 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3154 ok(size >= 142, "unexpected size: %u\n", size);
3156 buf = CryptMemAlloc(size);
3161 CERT_INFO *certInfo = (CERT_INFO *)buf;
3163 SetLastError(0xdeadbeef);
3164 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, buf, &size);
3166 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3168 ok(certInfo->SerialNumber.cbData == sizeof(serialNumber),
3169 "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData);
3171 ok(!memcmp(certInfo->SerialNumber.pbData, serialNumber,
3172 sizeof(serialNumber)), "unexpected serial number\n");
3174 ok(certInfo->Issuer.cbData == sizeof(issuer),
3175 "unexpected issuer size: %u\n", certInfo->Issuer.cbData);
3177 ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)),
3178 "unexpected issuer\n");
3184 static void test_decode_msg(void)
3186 test_decode_msg_update();
3187 test_decode_msg_get_param();
3190 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
3191 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
3192 static BYTE encodedPubKey[] = {
3193 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
3194 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
3196 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
3197 static BYTE mod_encoded[] = {
3198 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
3201 static void test_msg_control(void)
3203 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3207 CERT_INFO certInfo = { 0 };
3208 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
3209 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
3210 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
3213 ret = CryptMsgControl(NULL, 0, 0, NULL);
3216 /* Data encode messages don't allow any sort of control.. */
3217 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
3219 /* either with no prior update.. */
3220 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3222 SetLastError(0xdeadbeef);
3223 ret = CryptMsgControl(msg, 0, i, NULL);
3224 ok(!ret && GetLastError() == E_INVALIDARG,
3225 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3227 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3228 /* or after an update. */
3229 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3231 SetLastError(0xdeadbeef);
3232 ret = CryptMsgControl(msg, 0, i, NULL);
3233 ok(!ret && GetLastError() == E_INVALIDARG,
3234 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3238 /* Hash encode messages don't allow any sort of control.. */
3239 hashInfo.cbSize = sizeof(hashInfo);
3240 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
3241 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
3243 /* either with no prior update.. */
3244 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3246 SetLastError(0xdeadbeef);
3247 ret = CryptMsgControl(msg, 0, i, NULL);
3248 ok(!ret && GetLastError() == E_INVALIDARG,
3249 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3251 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3252 /* or after an update. */
3253 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3255 SetLastError(0xdeadbeef);
3256 ret = CryptMsgControl(msg, 0, i, NULL);
3257 ok(!ret && GetLastError() == E_INVALIDARG,
3258 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3262 /* Signed encode messages likewise don't allow any sort of control.. */
3263 signInfo.cbSize = sizeof(signInfo);
3264 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
3266 /* either before an update.. */
3267 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3269 SetLastError(0xdeadbeef);
3270 ret = CryptMsgControl(msg, 0, i, NULL);
3271 ok(!ret && GetLastError() == E_INVALIDARG,
3272 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3274 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3275 /* or after an update. */
3276 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3278 SetLastError(0xdeadbeef);
3279 ret = CryptMsgControl(msg, 0, i, NULL);
3280 ok(!ret && GetLastError() == E_INVALIDARG,
3281 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3285 /* Decode messages behave a bit differently. */
3286 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3287 /* Bad control type */
3288 SetLastError(0xdeadbeef);
3289 ret = CryptMsgControl(msg, 0, 0, NULL);
3290 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3291 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3292 SetLastError(0xdeadbeef);
3293 ret = CryptMsgControl(msg, 1, 0, NULL);
3294 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3295 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3296 /* Can't verify the hash of an indeterminate-type message */
3297 SetLastError(0xdeadbeef);
3298 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3299 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3300 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3302 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
3304 /* Can't decrypt an indeterminate-type message */
3305 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3306 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3307 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3312 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3314 /* Can't verify the hash of an empty message */
3315 SetLastError(0xdeadbeef);
3316 /* Crashes on some Win9x */
3317 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3319 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3320 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3322 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3324 /* Can't verify the signature of a hash message */
3325 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3326 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3327 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3328 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
3330 /* Oddly enough, this fails, crashes on some Win9x */
3331 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3332 ok(!ret, "Expected failure\n");
3335 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3337 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
3338 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3339 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3340 /* Can't decrypt an indeterminate-type message */
3341 SetLastError(0xdeadbeef);
3342 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3343 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3344 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3347 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3349 /* Can't verify the hash of a detached message before it's been updated. */
3350 SetLastError(0xdeadbeef);
3351 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3352 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3353 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3354 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3356 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3357 /* Still can't verify the hash of a detached message with the content
3358 * of the detached hash given..
3360 SetLastError(0xdeadbeef);
3361 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3362 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
3363 "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
3364 /* and giving the content of the message after attempting to verify the
3367 SetLastError(0xdeadbeef);
3368 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3371 (GetLastError() == NTE_BAD_HASH_STATE ||
3372 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3373 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
3374 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3375 "got %08x\n", GetLastError());
3378 /* Finally, verifying the hash of a detached message in the correct order:
3379 * 1. Update with the detached hash message
3380 * 2. Update with the content of the message
3381 * 3. Verifying the hash of the message
3384 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3386 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3388 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3389 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3390 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3391 SetLastError(0xdeadbeef);
3392 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3393 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3396 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3398 /* Can't verify the hash of a signed message */
3399 SetLastError(0xdeadbeef);
3400 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3401 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3402 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3403 /* Can't decrypt a signed message */
3404 SetLastError(0xdeadbeef);
3405 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3406 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3407 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3409 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3410 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3412 CryptMsgUpdate(msg, signedWithCertBareContent,
3413 sizeof(signedWithCertBareContent), TRUE);
3414 /* With an empty cert info, the signer can't be found in the message (and
3415 * the signature can't be verified.
3417 SetLastError(0xdeadbeef);
3418 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3419 ok(!ret && (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND ||
3420 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3421 "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n",
3423 /* The cert info is expected to have an issuer, serial number, and public
3426 certInfo.SerialNumber.cbData = sizeof(serialNum);
3427 certInfo.SerialNumber.pbData = serialNum;
3428 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3429 certInfo.Issuer.pbData = encodedCommonName;
3430 SetLastError(0xdeadbeef);
3431 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3432 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3433 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3434 "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError());
3436 /* This cert has a public key, but it's not in a usable form */
3437 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3439 ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
3440 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
3443 /* Crashes on some Win9x */
3444 /* Again, cert info needs to have a public key set */
3445 SetLastError(0xdeadbeef);
3446 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3448 (GetLastError() == CRYPT_E_ASN1_EOD ||
3449 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3450 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3451 /* The public key is supposed to be in encoded form.. */
3452 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3453 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3454 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
3455 SetLastError(0xdeadbeef);
3456 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3458 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3459 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3460 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3461 /* but not as a X509_PUBLIC_KEY_INFO.. */
3462 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3463 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
3464 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
3465 SetLastError(0xdeadbeef);
3466 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3468 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3469 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3470 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3471 /* This decodes successfully, but it doesn't match any key in the message */
3472 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
3473 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
3474 SetLastError(0xdeadbeef);
3475 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3476 /* In Wine's rsaenh, this fails to decode because the key length is too
3477 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
3482 (GetLastError() == NTE_BAD_SIGNATURE ||
3483 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3484 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3487 /* A message with no data doesn't have a valid signature */
3488 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3489 ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
3490 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
3493 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3494 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
3495 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
3496 SetLastError(0xdeadbeef);
3497 /* Crashes on some Win9x */
3498 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3500 (GetLastError() == NTE_BAD_SIGNATURE ||
3501 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3502 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3505 /* Finally, this succeeds */
3506 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3507 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3508 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3509 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3510 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3511 "CryptMsgControl failed: %08x\n", GetLastError());
3514 /* Test verifying signature of a detached signed message */
3515 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3517 ret = CryptMsgUpdate(msg, detachedSignedContent,
3518 sizeof(detachedSignedContent), TRUE);
3519 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3520 /* Can't verify the sig without having updated the data */
3521 SetLastError(0xdeadbeef);
3522 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3523 ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
3524 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3525 "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n",
3527 /* Now that the signature's been checked, can't do the final update */
3528 SetLastError(0xdeadbeef);
3529 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3532 (GetLastError() == NTE_BAD_HASH_STATE ||
3533 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3534 GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */
3535 broken(ret), /* Win9x */
3536 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3537 "got %08x\n", GetLastError());
3539 /* Updating with the detached portion of the message and the data of the
3540 * the message allows the sig to be verified.
3542 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3544 ret = CryptMsgUpdate(msg, detachedSignedContent,
3545 sizeof(detachedSignedContent), TRUE);
3546 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3547 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3548 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3549 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3550 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3551 "CryptMsgControl failed: %08x\n", GetLastError());
3554 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3556 decryptPara.cbSize = 0;
3557 SetLastError(0xdeadbeef);
3558 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3560 ok(!ret && GetLastError() == E_INVALIDARG,
3561 "expected E_INVALIDARG, got %08x\n", GetLastError());
3562 decryptPara.cbSize = sizeof(decryptPara);
3565 SetLastError(0xdeadbeef);
3566 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3567 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3568 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3570 SetLastError(0xdeadbeef);
3571 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
3572 sizeof(envelopedEmptyBareContent), TRUE);
3573 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3574 SetLastError(0xdeadbeef);
3575 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3577 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3578 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3581 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3583 SetLastError(0xdeadbeef);
3584 ret = CryptMsgUpdate(msg, envelopedBareMessage,
3585 sizeof(envelopedBareMessage), TRUE);
3586 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3587 SetLastError(0xdeadbeef);
3588 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3590 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
3591 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
3595 /* win9x has much less parameter checks and will crash on many tests
3596 * this code is from test_signed_msg_update()
3598 static BOOL detect_nt(void)
3601 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
3602 CERT_INFO certInfo = { 0 };
3604 if (!pCryptAcquireContextW)
3607 certInfo.SerialNumber.cbData = sizeof(serialNum);
3608 certInfo.SerialNumber.pbData = serialNum;
3609 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3610 certInfo.Issuer.pbData = encodedCommonName;
3611 signer.pCertInfo = &certInfo;
3612 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3614 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3615 PROV_RSA_FULL, CRYPT_NEWKEYSET);
3616 if (!ret && GetLastError() == NTE_EXISTS) {
3617 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3621 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
3624 CryptReleaseContext(signer.hCryptProv, 0);
3625 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
3626 CRYPT_DELETEKEYSET);
3631 static void test_msg_get_and_verify_signer(void)
3635 PCCERT_CONTEXT signer;
3642 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
3643 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3646 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3647 /* An empty message has no signer */
3648 SetLastError(0xdeadbeef);
3649 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3650 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3651 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3652 /* The signer is cleared on error */
3653 signer = (PCCERT_CONTEXT)0xdeadbeef;
3654 SetLastError(0xdeadbeef);
3655 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3656 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3657 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3658 ok(!signer, "expected signer to be NULL\n");
3659 /* The signer index is also cleared on error */
3660 signerIndex = 0xdeadbeef;
3661 SetLastError(0xdeadbeef);
3662 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3663 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3664 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3665 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
3666 /* An unsigned message (msgData isn't a signed message at all)
3667 * likewise has no signer.
3669 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3670 SetLastError(0xdeadbeef);
3671 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3672 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3673 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3676 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3677 /* A "signed" message created with no signer cert likewise has no signer */
3678 ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
3681 /* Crashes on most Win9x */
3682 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3683 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3684 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3688 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3689 /* A signed message succeeds, .. */
3690 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3691 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3692 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3693 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3694 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3695 /* the signer index can be retrieved, .. */
3696 signerIndex = 0xdeadbeef;
3697 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3698 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3699 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3701 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
3702 /* as can the signer cert. */
3703 signer = (PCCERT_CONTEXT)0xdeadbeef;
3704 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3705 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3706 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3708 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3709 "expected a valid signer\n");
3710 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3711 CertFreeCertificateContext(signer);
3712 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3714 signerIndex = 0xdeadbeef;
3715 SetLastError(0xdeadbeef);
3716 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3717 NULL, &signerIndex);
3718 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3719 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3720 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3721 * message signer not to be found.
3723 SetLastError(0xdeadbeef);
3724 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3726 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3727 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3728 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3729 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3730 * the message signer not to be found.
3732 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3733 CERT_STORE_CREATE_NEW_FLAG, NULL);
3734 SetLastError(0xdeadbeef);
3735 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3737 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3738 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3739 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3740 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3741 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3742 CERT_STORE_ADD_ALWAYS, NULL);
3743 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win98 */),
3744 "CertAddEncodedCertificateToStore failed: 0x%08x\n", GetLastError());
3745 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3746 * the signer succeeds.
3748 SetLastError(0xdeadbeef);
3749 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3751 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3752 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3753 CertCloseStore(store, 0);
3759 init_function_pointers();
3760 have_nt = detect_nt();
3762 win_skip("Win9x crashes on some parameter checks\n");
3764 /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
3765 if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
3767 win_skip("Some tests will crash on older crypt32 implementations\n");
3771 /* Basic parameter checking tests */
3772 test_msg_open_to_encode();
3773 test_msg_open_to_decode();
3774 test_msg_get_param();
3778 /* Message-type specific tests */
3782 test_enveloped_msg();
3785 test_msg_get_and_verify_signer();