2 * Unit test suite for crypt32.dll's CryptMsg functions
4 * Copyright 2007 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #define CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS
27 #define CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS
30 #include "wine/test.h"
32 static BOOL have_nt = TRUE;
33 static BOOL old_crypt32 = FALSE;
34 static char oid_rsa_md5[] = szOID_RSA_MD5;
36 static BOOL (WINAPI * pCryptAcquireContextA)
37 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
38 static BOOL (WINAPI * pCryptAcquireContextW)
39 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
41 static void init_function_pointers(void)
43 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
45 #define GET_PROC(dll, func) \
46 p ## func = (void *)GetProcAddress(dll, #func); \
48 trace("GetProcAddress(%s) failed\n", #func);
50 GET_PROC(hAdvapi32, CryptAcquireContextA)
51 GET_PROC(hAdvapi32, CryptAcquireContextW)
56 static void test_msg_open_to_encode(void)
61 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
63 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
65 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
70 SetLastError(0xdeadbeef);
71 msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
72 ok(!msg && GetLastError() == E_INVALIDARG,
73 "Expected E_INVALIDARG, got %x\n", GetLastError());
74 SetLastError(0xdeadbeef);
75 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
76 ok(!msg && GetLastError() == E_INVALIDARG,
77 "Expected E_INVALIDARG, got %x\n", GetLastError());
79 /* Bad message types */
80 SetLastError(0xdeadbeef);
81 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
82 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
83 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
84 SetLastError(0xdeadbeef);
85 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
87 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
88 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
89 SetLastError(0xdeadbeef);
90 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
91 CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
92 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
93 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
94 SetLastError(0xdeadbeef);
95 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
97 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
98 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
101 static void test_msg_open_to_decode(void)
104 CMSG_STREAM_INFO streamInfo = { 0 };
106 SetLastError(0xdeadbeef);
107 msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
108 ok(!msg && GetLastError() == E_INVALIDARG,
109 "Expected E_INVALIDARG, got %x\n", GetLastError());
112 SetLastError(0xdeadbeef);
113 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
114 ok(!msg && GetLastError() == E_INVALIDARG,
115 "Expected E_INVALIDARG, got %x\n", GetLastError());
116 SetLastError(0xdeadbeef);
117 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
118 ok(!msg && GetLastError() == E_INVALIDARG,
119 "Expected E_INVALIDARG, got %x\n", GetLastError());
121 /* The message type can be explicit... */
122 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
124 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
126 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
128 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
130 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
132 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
134 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
136 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
138 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
139 CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
140 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
143 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
144 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
146 /* or even invalid. */
147 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
149 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
151 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
152 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
155 /* And even though the stream info parameter "must be set to NULL" for
156 * CMSG_HASHED, it's still accepted.
158 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
160 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
164 static void test_msg_get_param(void)
168 DWORD size, i, value;
169 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
170 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
173 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
174 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
175 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
178 /* Decoded messages */
179 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
180 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
181 /* For decoded messages, the type is always available */
183 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
184 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
185 size = sizeof(value);
186 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
187 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
188 /* For this (empty) message, the type isn't set */
189 ok(value == 0, "Expected type 0, got %d\n", value);
192 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
194 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
195 /* For explicitly typed messages, the type is known. */
196 size = sizeof(value);
197 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
198 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
199 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
200 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
203 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
204 ok(!ret, "Parameter %d: expected failure\n", i);
208 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
210 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
211 size = sizeof(value);
212 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
213 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
214 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
215 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
218 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
219 ok(!ret, "Parameter %d: expected failure\n", i);
223 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
225 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
226 size = sizeof(value);
227 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
228 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
229 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
230 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
233 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
234 ok(!ret, "Parameter %d: expected failure\n", i);
238 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
240 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
241 size = sizeof(value);
242 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
243 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
244 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
245 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
248 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
249 ok(!ret, "Parameter %d: expected failure\n", i);
253 /* Explicitly typed messages get their types set, even if they're invalid */
254 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
256 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
257 size = sizeof(value);
258 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
259 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
260 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
263 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
264 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
265 size = sizeof(value);
266 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
267 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
268 ok(value == 1000, "Expected 1000, got %d\n", value);
272 static void test_msg_close(void)
277 /* NULL succeeds.. */
278 ret = CryptMsgClose(NULL);
279 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
280 /* but an arbitrary pointer crashes. */
282 ret = CryptMsgClose((HCRYPTMSG)1);
283 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
285 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
286 ret = CryptMsgClose(msg);
287 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
290 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
291 const BYTE *expected, DWORD expectedSize)
298 ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
299 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */ ||
300 GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x, for some params */),
301 "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
304 win_skip("parameter %d not supported, skipping tests\n", param);
307 buf = HeapAlloc(GetProcessHeap(), 0, size);
308 ret = CryptMsgGetParam(msg, param, 0, buf, &size);
309 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
310 ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
312 if (size == expectedSize && size)
313 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
314 HeapFree(GetProcessHeap(), 0, buf);
317 static void test_data_msg_open(void)
320 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
321 CMSG_STREAM_INFO streamInfo = { 0 };
322 char oid[] = "1.2.3";
324 /* The data message type takes no additional info */
325 SetLastError(0xdeadbeef);
326 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
328 ok(!msg && GetLastError() == E_INVALIDARG,
329 "Expected E_INVALIDARG, got %x\n", GetLastError());
330 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
332 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
335 /* An empty stream info is allowed. */
336 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
338 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
341 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
342 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
344 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
346 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
347 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
348 CMSG_DATA, NULL, oid, NULL);
349 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
351 /* and when a stream info is given, even though you're not supposed to be
352 * able to use anything but szOID_RSA_data when streaming is being used.
354 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
355 CMSG_DATA, NULL, oid, &streamInfo);
356 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
360 static const BYTE msgData[] = { 1, 2, 3, 4 };
362 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
368 static void test_data_msg_update(void)
372 CMSG_STREAM_INFO streamInfo = { 0 };
374 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
376 /* Can't update a message that wasn't opened detached with final = FALSE */
377 SetLastError(0xdeadbeef);
378 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
379 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
380 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
381 /* Updating it with final = TRUE succeeds */
382 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
383 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
384 /* Any subsequent update will fail, as the last was final */
385 SetLastError(0xdeadbeef);
386 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
387 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
388 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
391 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
393 /* Can't update a message with no data */
394 SetLastError(0xdeadbeef);
395 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
396 /* This test returns FALSE on XP and earlier but TRUE on Vista, so can't be tested.
397 * GetLastError is either E_INVALIDARG (NT) or unset (9x/Vista), so it doesn't
398 * make sense to test this.
401 /* Curiously, a valid update will now fail as well, presumably because of
402 * the last (invalid, but final) update.
404 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
405 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
406 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
409 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
410 CMSG_DATA, NULL, NULL, NULL);
413 /* Doesn't appear to be able to update CMSG-DATA with non-final updates.
414 * On Win9x, this sometimes succeeds, sometimes fails with
415 * GetLastError() == 0, so it's not worth checking there.
417 SetLastError(0xdeadbeef);
418 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
420 (GetLastError() == E_INVALIDARG ||
421 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
422 "Expected E_INVALIDARG, got %x\n", GetLastError());
423 SetLastError(0xdeadbeef);
424 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
426 (GetLastError() == E_INVALIDARG ||
427 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
428 "Expected E_INVALIDARG, got %x\n", GetLastError());
431 skip("not updating CMSG_DATA with a non-final update\n");
432 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
433 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
438 /* Calling update after opening with an empty stream info (with a bogus
439 * output function) yields an error:
441 /* Crashes on some Win9x */
442 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
444 SetLastError(0xdeadbeef);
445 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
446 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
447 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
448 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
452 /* Calling update with a valid output function succeeds, even if the data
453 * exceeds the size specified in the stream info.
455 streamInfo.pfnStreamOutput = nop_stream_output;
456 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
458 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
459 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
460 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
461 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
465 static void test_data_msg_get_param(void)
470 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
472 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
475 /* Content and bare content are always gettable when not streaming */
477 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
478 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
480 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
481 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
482 /* But for this type of message, the signer and hash aren't applicable,
483 * and the type isn't available.
486 SetLastError(0xdeadbeef);
487 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
488 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
489 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
490 SetLastError(0xdeadbeef);
491 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
492 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
493 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
494 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
495 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
496 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
499 /* Can't get content or bare content when streaming */
500 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
502 SetLastError(0xdeadbeef);
503 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
504 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
505 "Expected E_INVALIDARG, got %x\n", GetLastError());
506 SetLastError(0xdeadbeef);
507 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
508 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
509 "Expected E_INVALIDARG, got %x\n", GetLastError());
513 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
514 static const BYTE dataEmptyContent[] = {
515 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
517 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
518 static const BYTE dataContent[] = {
519 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
520 0x04,0x04,0x01,0x02,0x03,0x04 };
525 CRYPT_DATA_BLOB *updates;
528 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
529 DWORD cb, BOOL final)
531 struct update_accum *accum = (struct update_accum *)pvArg;
535 accum->updates = CryptMemRealloc(accum->updates,
536 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
538 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
541 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
543 blob->pbData = CryptMemAlloc(cb);
546 memcpy(blob->pbData, pb, cb);
555 /* The updates of a (bogus) definite-length encoded message */
556 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
557 0x07,0x01,0xa0,0x02,0x04,0x00 };
558 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
559 static CRYPT_DATA_BLOB b1[] = {
564 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
565 /* The updates of a definite-length encoded message */
566 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
567 0x07,0x01,0xa0,0x06,0x04,0x04 };
568 static CRYPT_DATA_BLOB b2[] = {
572 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
573 /* The updates of an indefinite-length encoded message */
574 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
575 0x07,0x01,0xa0,0x80,0x24,0x80 };
576 static BYTE u5[] = { 0x04,0x04 };
577 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
578 static CRYPT_DATA_BLOB b3[] = {
586 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
588 static void check_updates(LPCSTR header, const struct update_accum *expected,
589 const struct update_accum *got)
593 ok(expected->cUpdates == got->cUpdates,
594 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
596 if (expected->cUpdates == got->cUpdates)
597 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
599 ok(expected->updates[i].cbData == got->updates[i].cbData,
600 "%s, update %d: expected %d bytes, got %d\n", header, i,
601 expected->updates[i].cbData, got->updates[i].cbData);
602 if (expected->updates[i].cbData && expected->updates[i].cbData ==
603 got->updates[i].cbData)
604 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
605 got->updates[i].cbData), "%s, update %d: unexpected value\n",
610 /* Frees the updates stored in accum */
611 static void free_updates(struct update_accum *accum)
615 for (i = 0; i < accum->cUpdates; i++)
616 CryptMemFree(accum->updates[i].pbData);
617 CryptMemFree(accum->updates);
618 accum->updates = NULL;
622 static void test_data_msg_encoding(void)
626 static char oid[] = "1.2.3";
627 struct update_accum accum = { 0, NULL };
628 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
630 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
632 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
633 dataEmptyBareContent, sizeof(dataEmptyBareContent));
634 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
635 sizeof(dataEmptyContent));
636 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
637 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
638 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
639 dataBareContent, sizeof(dataBareContent));
640 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
641 sizeof(dataContent));
643 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
644 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
645 CMSG_DATA, NULL, NULL, NULL);
646 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
647 dataEmptyBareContent, sizeof(dataEmptyBareContent));
648 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
649 sizeof(dataEmptyContent));
650 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
651 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
652 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
653 dataBareContent, sizeof(dataBareContent));
654 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
655 sizeof(dataContent));
657 /* The inner OID is apparently ignored */
658 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
660 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
661 dataEmptyBareContent, sizeof(dataEmptyBareContent));
662 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
663 dataEmptyContent, sizeof(dataEmptyContent));
664 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
665 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
666 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
667 dataBareContent, sizeof(dataBareContent));
668 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
669 sizeof(dataContent));
671 /* A streaming message is DER encoded if the length is not 0xffffffff, but
672 * curiously, updates aren't validated to make sure they don't exceed the
673 * stated length. (The resulting output will of course fail to decode.)
675 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
677 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
678 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
680 check_updates("bogus data message with definite length", &a1, &accum);
681 free_updates(&accum);
682 /* A valid definite-length encoding: */
683 streamInfo.cbContent = sizeof(msgData);
684 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
686 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
688 check_updates("data message with definite length", &a2, &accum);
689 free_updates(&accum);
690 /* An indefinite-length encoding: */
691 streamInfo.cbContent = 0xffffffff;
692 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
694 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
695 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
697 check_updates("data message with indefinite length", &a3, &accum);
698 free_updates(&accum);
701 static void test_data_msg(void)
703 test_data_msg_open();
704 test_data_msg_update();
705 test_data_msg_get_param();
706 test_data_msg_encoding();
709 static void test_hash_msg_open(void)
712 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
713 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
715 SetLastError(0xdeadbeef);
716 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
718 ok(!msg && GetLastError() == E_INVALIDARG,
719 "Expected E_INVALIDARG, got %x\n", GetLastError());
720 hashInfo.cbSize = sizeof(hashInfo);
721 SetLastError(0xdeadbeef);
722 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
724 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
725 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
726 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
727 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
729 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
731 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
732 CMSG_HASHED, &hashInfo, NULL, NULL);
733 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
735 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
736 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
737 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
741 static void test_hash_msg_update(void)
745 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
746 { oid_rsa_md5, { 0, NULL } }, NULL };
747 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
749 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
750 CMSG_HASHED, &hashInfo, NULL, NULL);
751 /* Detached hashed messages opened in non-streaming mode allow non-final
754 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
755 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
756 /* including non-final updates with no data.. */
757 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
758 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
759 /* and final updates with no data. */
760 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
761 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
762 /* But no updates are allowed after the final update. */
763 SetLastError(0xdeadbeef);
764 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
765 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
766 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
767 SetLastError(0xdeadbeef);
768 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
769 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
770 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
772 /* Non-detached messages, in contrast, don't allow non-final updates in
773 * non-streaming mode.
775 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
777 SetLastError(0xdeadbeef);
778 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
779 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
780 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
781 /* Final updates (including empty ones) are allowed. */
782 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
783 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
785 /* And, of course, streaming mode allows non-final updates */
786 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
788 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
789 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
791 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
792 * to be a bug, it isn't actually used - see encoding tests.)
794 streamInfo.pfnStreamOutput = NULL;
795 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
797 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
798 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
802 static const BYTE emptyHashParam[] = {
803 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
806 static void test_hash_msg_get_param(void)
810 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
811 { oid_rsa_md5, { 0, NULL } }, NULL };
813 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
816 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
818 /* Content and bare content are always gettable for non-streamed messages */
820 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
821 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
822 "CryptMsgGetParam failed: %08x\n", GetLastError());
824 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
825 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
826 "CryptMsgGetParam failed: %08x\n", GetLastError());
827 /* For an encoded hash message, the hash data aren't available */
828 SetLastError(0xdeadbeef);
829 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
830 ok(!ret && (GetLastError() == CRYPT_E_INVALID_MSG_TYPE ||
831 GetLastError() == OSS_LIMITED /* Win9x */),
832 "Expected CRYPT_E_INVALID_MSG_TYPE or OSS_LIMITED, got %08x\n",
834 /* The hash is also available. */
836 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
837 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
838 ok(size == sizeof(buf), "Unexpected size %d\n", size);
839 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
840 if (size == sizeof(buf))
841 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
842 /* By getting the hash, further updates are not allowed */
843 SetLastError(0xdeadbeef);
844 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
846 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
847 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
848 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
849 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
850 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
852 /* Even after a final update, the hash data aren't available */
853 SetLastError(0xdeadbeef);
854 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
855 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
856 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
857 /* The version is also available, and should be zero for this message. */
859 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
860 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
861 "CryptMsgGetParam failed: %08x\n", GetLastError());
862 size = sizeof(value);
863 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
864 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
865 "CryptMsgGetParam failed: %08x\n", GetLastError());
867 ok(value == 0, "Expected version 0, got %d\n", value);
868 /* As usual, the type isn't available. */
869 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
870 ok(!ret, "Expected failure\n");
873 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
875 /* Streamed messages don't allow you to get the content or bare content. */
876 SetLastError(0xdeadbeef);
877 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
878 ok(!ret && (GetLastError() == E_INVALIDARG ||
879 GetLastError() == OSS_LIMITED /* Win9x */),
880 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
881 SetLastError(0xdeadbeef);
882 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
883 ok(!ret && (GetLastError() == E_INVALIDARG ||
884 GetLastError() == OSS_LIMITED /* Win9x */),
885 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
886 /* The hash is still available. */
888 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
889 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
890 ok(size == sizeof(buf), "Unexpected size %d\n", size);
891 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
892 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
893 if (size == sizeof(buf))
894 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
895 /* After updating the hash, further updates aren't allowed on streamed
898 SetLastError(0xdeadbeef);
899 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
901 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
902 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
903 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
904 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
905 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
910 static const BYTE hashEmptyBareContent[] = {
911 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
912 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
913 static const BYTE hashEmptyContent[] = {
914 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
915 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
916 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
917 static const BYTE hashBareContent[] = {
918 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
919 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
920 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
921 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
922 static const BYTE hashContent[] = {
923 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
924 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
925 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
926 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
927 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
929 static const BYTE detachedHashNonFinalBareContent[] = {
930 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
931 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
932 0x07,0x01,0x04,0x00 };
933 static const BYTE detachedHashNonFinalContent[] = {
934 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
935 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
936 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
937 0x07,0x01,0x04,0x00 };
938 static const BYTE detachedHashBareContent[] = {
939 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
940 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
941 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
942 0x9d,0x2a,0x8f,0x26,0x2f };
943 static const BYTE detachedHashContent[] = {
944 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
945 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
946 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
947 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
948 0x9d,0x2a,0x8f,0x26,0x2f };
950 static void test_hash_msg_encoding(void)
953 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
955 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
956 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
958 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
959 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
961 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
962 hashEmptyBareContent, sizeof(hashEmptyBareContent));
963 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
964 hashEmptyContent, sizeof(hashEmptyContent));
965 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
966 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
967 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
968 hashBareContent, sizeof(hashBareContent));
969 check_param("hash content", msg, CMSG_CONTENT_PARAM,
970 hashContent, sizeof(hashContent));
972 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
973 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
974 CMSG_HASHED, &hashInfo, NULL, NULL);
975 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
976 hashEmptyBareContent, sizeof(hashEmptyBareContent));
977 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
978 hashEmptyContent, sizeof(hashEmptyContent));
979 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
980 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
981 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
982 hashBareContent, sizeof(hashBareContent));
983 check_param("hash content", msg, CMSG_CONTENT_PARAM,
984 hashContent, sizeof(hashContent));
986 /* Same test, but with CMSG_DETACHED_FLAG set */
987 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
988 CMSG_HASHED, &hashInfo, NULL, NULL);
989 check_param("detached hash empty bare content", msg,
990 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
991 sizeof(hashEmptyBareContent));
992 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
993 hashEmptyContent, sizeof(hashEmptyContent));
994 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
995 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
996 check_param("detached hash not final bare content", msg,
997 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
998 sizeof(detachedHashNonFinalBareContent));
999 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
1000 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
1001 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1002 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1003 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1004 detachedHashBareContent, sizeof(detachedHashBareContent));
1005 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1006 detachedHashContent, sizeof(detachedHashContent));
1007 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1008 detachedHashBareContent, sizeof(detachedHashBareContent));
1009 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1010 detachedHashContent, sizeof(detachedHashContent));
1012 /* In what appears to be a bug, streamed updates to hash messages don't
1013 * call the output function.
1015 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
1017 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1018 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1019 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1020 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1022 check_updates("empty hash message", &empty_accum, &accum);
1023 free_updates(&accum);
1025 streamInfo.cbContent = sizeof(msgData);
1026 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
1028 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1029 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1031 check_updates("hash message", &empty_accum, &accum);
1032 free_updates(&accum);
1034 streamInfo.cbContent = sizeof(msgData);
1035 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
1036 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
1037 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1038 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1040 check_updates("detached hash message", &empty_accum, &accum);
1041 free_updates(&accum);
1044 static void test_hash_msg(void)
1046 test_hash_msg_open();
1047 test_hash_msg_update();
1048 test_hash_msg_get_param();
1049 test_hash_msg_encoding();
1052 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1054 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1056 static BYTE serialNum[] = { 1 };
1057 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1058 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1060 static void test_signed_msg_open(void)
1064 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1065 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1066 CERT_INFO certInfo = { 0 };
1068 SetLastError(0xdeadbeef);
1069 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1071 ok(!msg && GetLastError() == E_INVALIDARG,
1072 "Expected E_INVALIDARG, got %x\n", GetLastError());
1073 signInfo.cbSize = sizeof(signInfo);
1074 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1076 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1079 signInfo.cSigners = 1;
1080 signInfo.rgSigners = &signer;
1081 /* With signer.pCertInfo unset, attempting to open this message this
1084 signer.pCertInfo = &certInfo;
1085 /* The cert info must contain a serial number and an issuer. */
1086 SetLastError(0xdeadbeef);
1087 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1089 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1090 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1091 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1092 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1095 certInfo.SerialNumber.cbData = sizeof(serialNum);
1096 certInfo.SerialNumber.pbData = serialNum;
1097 SetLastError(0xdeadbeef);
1098 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1100 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1101 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1102 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1103 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1106 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1107 certInfo.Issuer.pbData = encodedCommonName;
1108 SetLastError(0xdeadbeef);
1109 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1111 ok(!msg && (GetLastError() == E_INVALIDARG ||
1112 GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1113 "Expected E_INVALIDARG or CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1115 /* The signer's hCryptProv must be set to something. Whether it's usable
1116 * or not will be checked after the hash algorithm is checked (see next
1119 signer.hCryptProv = 1;
1120 SetLastError(0xdeadbeef);
1121 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1123 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1124 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1125 /* The signer's hash algorithm must also be set. */
1126 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1127 SetLastError(0xdeadbeef);
1128 /* Crashes in advapi32 in wine, don't do it */
1130 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1131 &signInfo, NULL, NULL);
1132 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1133 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1135 /* The signer's hCryptProv must also be valid. */
1136 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1137 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1138 if (!ret && GetLastError() == NTE_EXISTS) {
1139 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1142 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1145 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1147 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1151 /* pCertInfo must still be set, but can be empty if the SignerId's issuer
1152 * and serial number are set.
1154 certInfo.Issuer.cbData = 0;
1155 certInfo.SerialNumber.cbData = 0;
1156 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1157 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1158 sizeof(encodedCommonName);
1159 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1160 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1162 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1163 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1165 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1168 CryptReleaseContext(signer.hCryptProv, 0);
1169 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1170 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1173 static const BYTE privKey[] = {
1174 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1175 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1176 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1177 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1178 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1179 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1180 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1181 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1182 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1183 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1184 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1185 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1186 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1187 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1188 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1189 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1190 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1191 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1192 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1193 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1194 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1195 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1196 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1197 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1198 static BYTE pubKey[] = {
1199 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1200 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1201 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1202 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1203 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1205 static void test_signed_msg_update(void)
1209 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1210 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1211 CERT_INFO certInfo = { 0 };
1214 certInfo.SerialNumber.cbData = sizeof(serialNum);
1215 certInfo.SerialNumber.pbData = serialNum;
1216 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1217 certInfo.Issuer.pbData = encodedCommonName;
1218 signer.pCertInfo = &certInfo;
1219 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1220 signInfo.cSigners = 1;
1221 signInfo.rgSigners = &signer;
1223 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1224 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1225 if (!ret && GetLastError() == NTE_EXISTS) {
1226 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1229 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1232 skip("No context for tests\n");
1236 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1237 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1238 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1239 /* Detached CMSG_SIGNED allows non-final updates. */
1240 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1241 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1242 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1243 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1244 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1245 /* The final update requires a private key in the hCryptProv, in order to
1246 * generate the signature.
1248 SetLastError(0xdeadbeef);
1249 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1251 (GetLastError() == NTE_BAD_KEYSET ||
1252 GetLastError() == NTE_NO_KEY ||
1253 broken(GetLastError() == ERROR_SUCCESS)), /* Some Win9x */
1254 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1255 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1257 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1258 /* The final update should be able to succeed now that a key exists, but
1259 * the previous (invalid) final update prevents it.
1261 SetLastError(0xdeadbeef);
1262 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1263 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1264 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1267 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1268 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1269 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1270 /* Detached CMSG_SIGNED allows non-final updates. */
1271 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1272 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1273 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1274 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1275 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1276 /* Now that the private key exists, the final update can succeed (even
1279 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1280 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1281 /* But no updates are allowed after the final update. */
1282 SetLastError(0xdeadbeef);
1283 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1284 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1285 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1286 SetLastError(0xdeadbeef);
1287 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1288 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1289 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1292 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1294 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1295 /* Non-detached messages don't allow non-final updates.. */
1296 SetLastError(0xdeadbeef);
1297 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1298 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1299 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1300 /* but they do allow final ones. */
1301 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1302 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1304 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1306 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1307 /* They also allow final updates with no data. */
1308 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1309 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1312 CryptDestroyKey(key);
1313 CryptReleaseContext(signer.hCryptProv, 0);
1314 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1315 CRYPT_DELETEKEYSET);
1318 static const BYTE signedEmptyBareContent[] = {
1319 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1320 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1321 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1322 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1323 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1324 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1325 static const BYTE signedEmptyContent[] = {
1326 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1327 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1328 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1329 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1330 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1331 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1332 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1333 static const BYTE detachedSignedBareContent[] = {
1334 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1335 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1336 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1337 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1338 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1339 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1340 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1341 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1342 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1343 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1344 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1345 static const BYTE detachedSignedContent[] = {
1346 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1347 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1348 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1349 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1350 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1351 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1352 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1353 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1354 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1355 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1356 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1357 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1358 static const BYTE signedBareContent[] = {
1359 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1360 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1361 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1362 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1363 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1364 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1365 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1366 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1367 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1368 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1369 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1370 static const BYTE signedContent[] = {
1371 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1372 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1373 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1374 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1375 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1376 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1377 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1378 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1379 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1380 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1381 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1382 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1384 static const BYTE signedHash[] = {
1385 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1387 static const BYTE signedKeyIdEmptyContent[] = {
1388 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
1389 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1390 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
1391 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1392 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1393 static const BYTE signedEncodedSigner[] = {
1394 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1395 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1396 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1397 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1398 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1399 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1400 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1401 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1402 static const BYTE signedWithAuthAttrsBareContent[] = {
1403 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1404 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1405 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1406 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1407 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1408 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1409 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1410 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1411 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1412 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1413 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1414 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1415 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1416 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1417 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1418 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1419 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1420 0xff,0xc6,0x33,0x63,0x34 };
1421 static BYTE cert[] = {
1422 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1423 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1424 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1425 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1426 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1427 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1428 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1429 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1430 0xff,0x02,0x01,0x01 };
1431 static BYTE v1CertWithPubKey[] = {
1432 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1433 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1434 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1435 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1436 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1437 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1438 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1439 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1440 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1441 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1443 static const BYTE signedWithCertEmptyBareContent[] = {
1444 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1445 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1446 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1447 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1448 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1449 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1450 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1451 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1452 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1453 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1454 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1455 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1456 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1457 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1458 static const BYTE signedWithCertBareContent[] = {
1459 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1460 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1461 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1462 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1463 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1464 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1465 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1466 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1467 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1468 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1469 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1470 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1471 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1472 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1473 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1474 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1475 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1476 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1477 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1478 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1479 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1480 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1481 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1482 0x30,0x30,0x30,0x30,0x5a };
1483 static const BYTE signedWithCrlEmptyBareContent[] = {
1484 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1485 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1486 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1487 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1488 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1489 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1490 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1491 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1492 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1493 static const BYTE signedWithCrlBareContent[] = {
1494 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1495 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1496 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1497 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1498 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1499 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1500 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1501 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1502 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1503 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1504 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1505 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1506 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1507 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1509 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1510 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1511 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1512 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1513 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1514 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1515 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1516 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1517 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1518 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1519 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1520 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1521 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1522 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1523 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1524 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1525 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1526 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1528 static const BYTE signedWithCertAndCrlBareContent[] = {
1529 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1530 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1531 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1532 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1533 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1534 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1535 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1536 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1537 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1538 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1539 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1540 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1541 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1542 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1543 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1544 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1545 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1546 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1547 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1548 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1549 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1550 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1551 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1552 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1553 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1554 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1555 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1556 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1557 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1558 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1559 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1560 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1561 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1562 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1563 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1564 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1565 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1566 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1567 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1568 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1569 static BYTE v1CertWithValidPubKey[] = {
1570 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1571 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1572 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1573 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1574 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1575 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1576 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1577 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1578 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1579 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1580 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1581 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1582 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1583 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1584 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1585 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1586 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1587 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1588 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1589 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1590 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1591 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1592 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1593 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1594 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1595 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1596 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1597 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1598 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1599 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1600 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1601 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1602 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1603 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1604 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1605 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1607 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1608 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1609 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1610 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1611 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1612 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1613 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1614 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1615 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1616 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1617 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1618 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1619 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1620 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1621 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1622 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1623 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1624 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1625 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1626 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1627 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1628 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1629 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1630 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1631 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1632 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1633 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1634 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1636 static void test_signed_msg_encoding(void)
1639 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1640 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1641 CERT_INFO certInfo = { 0 };
1642 CERT_BLOB encodedCert = { sizeof(cert), cert };
1643 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1644 char oid_common_name[] = szOID_COMMON_NAME;
1645 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1646 encodedCommonName };
1647 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1652 certInfo.SerialNumber.cbData = sizeof(serialNum);
1653 certInfo.SerialNumber.pbData = serialNum;
1654 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1655 certInfo.Issuer.pbData = encodedCommonName;
1656 signer.pCertInfo = &certInfo;
1657 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1658 signInfo.cSigners = 1;
1659 signInfo.rgSigners = &signer;
1661 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1662 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1663 if (!ret && GetLastError() == NTE_EXISTS) {
1664 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1667 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1670 skip("No context for tests\n");
1674 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1676 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1678 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1679 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1680 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1682 check_param("detached signed empty bare content", msg,
1683 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1684 sizeof(signedEmptyBareContent));
1685 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1686 signedEmptyContent, sizeof(signedEmptyContent));
1687 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1688 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1689 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1690 signedHash, sizeof(signedHash));
1691 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1692 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1693 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1694 detachedSignedContent, sizeof(detachedSignedContent));
1695 SetLastError(0xdeadbeef);
1696 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1697 ok(!ret && (GetLastError() == CRYPT_E_INVALID_INDEX ||
1698 broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */)),
1699 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1700 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1701 signedEncodedSigner, sizeof(signedEncodedSigner));
1705 certInfo.SerialNumber.cbData = 0;
1706 certInfo.Issuer.cbData = 0;
1707 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1708 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1709 U(signer.SignerId).KeyId.pbData = serialNum;
1710 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1712 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1713 check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM,
1714 signedKeyIdEmptyContent, sizeof(signedKeyIdEmptyContent));
1717 certInfo.SerialNumber.cbData = sizeof(serialNum);
1718 certInfo.SerialNumber.pbData = serialNum;
1719 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1720 certInfo.Issuer.pbData = encodedCommonName;
1721 signer.SignerId.dwIdChoice = 0;
1722 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1724 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1726 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1727 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1728 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1729 signedEmptyContent, sizeof(signedEmptyContent));
1730 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1731 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1732 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1733 signedBareContent, sizeof(signedBareContent));
1734 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1735 signedContent, sizeof(signedContent));
1739 signer.cAuthAttr = 1;
1740 signer.rgAuthAttr = &attr;
1741 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1743 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1745 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1746 check_param("signed with auth attrs bare content", msg,
1747 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1748 sizeof(signedWithAuthAttrsBareContent));
1752 signer.cAuthAttr = 0;
1753 signInfo.rgCertEncoded = &encodedCert;
1754 signInfo.cCertEncoded = 1;
1755 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1757 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1759 check_param("signed with cert empty bare content", msg,
1760 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1761 sizeof(signedWithCertEmptyBareContent));
1762 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1763 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1764 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1765 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1769 signInfo.cCertEncoded = 0;
1770 signInfo.rgCrlEncoded = &encodedCrl;
1771 signInfo.cCrlEncoded = 1;
1772 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1774 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1776 check_param("signed with crl empty bare content", msg,
1777 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1778 sizeof(signedWithCrlEmptyBareContent));
1779 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1780 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1781 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1782 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1786 signInfo.cCertEncoded = 1;
1787 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1789 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1791 check_param("signed with cert and crl empty bare content", msg,
1792 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1793 sizeof(signedWithCertAndCrlEmptyBareContent));
1794 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1795 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1796 check_param("signed with cert and crl bare content", msg,
1797 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1798 sizeof(signedWithCertAndCrlBareContent));
1802 /* Test with a cert with a (bogus) public key */
1803 signInfo.cCrlEncoded = 0;
1804 encodedCert.cbData = sizeof(v1CertWithPubKey);
1805 encodedCert.pbData = v1CertWithPubKey;
1806 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1808 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1809 check_param("signedWithCertWithPubKeyBareContent", msg,
1810 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1811 sizeof(signedWithCertWithPubKeyBareContent));
1814 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1815 encodedCert.pbData = v1CertWithValidPubKey;
1816 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1818 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1819 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1820 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1821 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1822 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1823 check_param("signedWithCertWithValidPubKeyContent", msg,
1824 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1825 sizeof(signedWithCertWithValidPubKeyContent));
1828 CryptDestroyKey(key);
1829 CryptReleaseContext(signer.hCryptProv, 0);
1830 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1831 CRYPT_DELETEKEYSET);
1834 static void test_signed_msg_get_param(void)
1838 DWORD size, value = 0;
1839 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1840 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1841 CERT_INFO certInfo = { 0 };
1843 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1845 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1847 /* Content and bare content are always gettable */
1849 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1850 ok(ret || broken(!ret /* Win9x */), "CryptMsgGetParam failed: %08x\n",
1854 skip("message parameters are broken, skipping tests\n");
1858 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1859 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1860 /* For "signed" messages, so is the version. */
1862 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1863 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1864 size = sizeof(value);
1865 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1866 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1867 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1868 /* But for this message, with no signers, the hash and signer aren't
1872 SetLastError(0xdeadbeef);
1873 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1874 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1875 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1876 SetLastError(0xdeadbeef);
1877 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1878 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1879 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1880 /* As usual, the type isn't available. */
1881 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1882 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1883 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1887 certInfo.SerialNumber.cbData = sizeof(serialNum);
1888 certInfo.SerialNumber.pbData = serialNum;
1889 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1890 certInfo.Issuer.pbData = encodedCommonName;
1891 signer.pCertInfo = &certInfo;
1892 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1893 signInfo.cSigners = 1;
1894 signInfo.rgSigners = &signer;
1896 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1897 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1898 if (!ret && GetLastError() == NTE_EXISTS) {
1899 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1902 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1905 skip("No context for tests\n");
1909 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1911 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1913 /* This message, with one signer, has the hash and signer for index 0
1914 * available, but not for other indexes.
1917 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1918 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1919 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1920 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1922 SetLastError(0xdeadbeef);
1923 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1924 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1925 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1926 SetLastError(0xdeadbeef);
1927 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1928 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1929 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1930 /* As usual, the type isn't available. */
1931 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1932 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1933 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1937 /* Opening the message using the CMS fields.. */
1938 certInfo.SerialNumber.cbData = 0;
1939 certInfo.Issuer.cbData = 0;
1940 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1941 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1942 sizeof(encodedCommonName);
1943 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1944 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1946 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1947 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1948 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1949 if (!ret && GetLastError() == NTE_EXISTS)
1950 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1952 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1953 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1954 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1955 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1956 /* still results in the version being 1 when the issuer and serial number
1957 * are used and no additional CMS fields are used.
1959 size = sizeof(value);
1960 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1961 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE),
1962 "CryptMsgGetParam failed: %08x\n", GetLastError());
1964 ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value);
1965 /* Apparently the encoded signer can be retrieved.. */
1966 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1967 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1968 /* but the signer info, CMS signer info, and cert ID can't be. */
1969 SetLastError(0xdeadbeef);
1970 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1971 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1972 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1973 SetLastError(0xdeadbeef);
1974 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1975 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1976 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1977 SetLastError(0xdeadbeef);
1978 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1979 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1980 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1983 /* Using the KeyId field of the SignerId results in the version becoming
1986 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1987 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1988 U(signer.SignerId).KeyId.pbData = serialNum;
1989 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1990 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1991 if (!ret && GetLastError() == NTE_EXISTS)
1992 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1994 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1995 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1996 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1997 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1998 size = sizeof(value);
1999 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
2000 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2002 ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value);
2003 /* Even for a CMS message, the signer can be retrieved.. */
2004 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
2005 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2006 /* but the signer info, CMS signer info, and cert ID can't be. */
2007 SetLastError(0xdeadbeef);
2008 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2009 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2010 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2011 SetLastError(0xdeadbeef);
2012 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2013 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2014 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2015 SetLastError(0xdeadbeef);
2016 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
2017 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2018 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2021 CryptReleaseContext(signer.hCryptProv, 0);
2022 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
2023 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2026 static void test_signed_msg(void)
2028 test_signed_msg_open();
2029 test_signed_msg_update();
2030 test_signed_msg_encoding();
2031 test_signed_msg_get_param();
2034 static char oid_rsa_rc4[] = szOID_RSA_RC4;
2036 static void test_enveloped_msg_open(void)
2040 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { 0 };
2041 PCCERT_CONTEXT context;
2043 SetLastError(0xdeadbeef);
2044 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2045 &envelopedInfo, NULL, NULL);
2047 ok(!msg && GetLastError() == E_INVALIDARG,
2048 "expected E_INVALIDARG, got %08x\n", GetLastError());
2050 envelopedInfo.cbSize = sizeof(envelopedInfo);
2051 SetLastError(0xdeadbeef);
2052 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2053 &envelopedInfo, NULL, NULL);
2056 (GetLastError() == CRYPT_E_UNKNOWN_ALGO ||
2057 GetLastError() == E_INVALIDARG), /* Win9x */
2058 "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", GetLastError());
2060 envelopedInfo.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4;
2061 SetLastError(0xdeadbeef);
2062 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2063 &envelopedInfo, NULL, NULL);
2066 broken(!msg), /* Win9x */
2067 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2070 envelopedInfo.cRecipients = 1;
2073 SetLastError(0xdeadbeef);
2074 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2075 &envelopedInfo, NULL, NULL);
2077 ok(!msg && GetLastError() == E_INVALIDARG,
2078 "expected E_INVALIDARG, got %08x\n", GetLastError());
2081 SetLastError(0xdeadbeef);
2082 context = CertCreateCertificateContext(X509_ASN_ENCODING,
2083 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
2086 envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo;
2087 SetLastError(0xdeadbeef);
2088 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2089 &envelopedInfo, NULL, NULL);
2091 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2095 win_skip("failed to create certificate context, skipping a test\n");
2097 SetLastError(0xdeadbeef);
2098 ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL,
2099 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
2100 ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
2101 SetLastError(0xdeadbeef);
2102 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2103 &envelopedInfo, NULL, NULL);
2105 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2108 CryptReleaseContext(envelopedInfo.hCryptProv, 0);
2109 CertFreeCertificateContext(context);
2112 static void test_enveloped_msg_update(void)
2116 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2117 { oid_rsa_rc4, { 0, NULL } }, NULL };
2118 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
2120 SetLastError(0xdeadbeef);
2121 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2122 &envelopedInfo, NULL, NULL);
2125 broken(!msg), /* Win9x */
2126 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2129 SetLastError(0xdeadbeef);
2130 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2132 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2133 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2134 SetLastError(0xdeadbeef);
2135 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2137 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2138 SetLastError(0xdeadbeef);
2139 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2141 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2142 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2145 SetLastError(0xdeadbeef);
2146 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2147 &envelopedInfo, NULL, NULL);
2150 broken(!msg), /* Win9x */
2151 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2154 SetLastError(0xdeadbeef);
2155 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2157 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2158 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2159 SetLastError(0xdeadbeef);
2160 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2163 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2164 "CryptMsgUpdate failed: %08x\n", GetLastError());
2165 SetLastError(0xdeadbeef);
2166 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2168 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2169 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2172 SetLastError(0xdeadbeef);
2173 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2174 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2177 broken(!msg), /* Win9x */
2178 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2181 SetLastError(0xdeadbeef);
2182 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2184 ok(!ret && GetLastError() == E_INVALIDARG,
2185 "expected E_INVALIDARG, got %08x\n", GetLastError());
2186 SetLastError(0xdeadbeef);
2187 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2189 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2192 SetLastError(0xdeadbeef);
2193 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2194 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2197 broken(!msg), /* Win9x */
2198 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2201 SetLastError(0xdeadbeef);
2202 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2204 ok(!ret && GetLastError() == E_INVALIDARG,
2205 "expected E_INVALIDARG, got %08x\n", GetLastError());
2206 SetLastError(0xdeadbeef);
2207 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2210 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2211 "CryptMsgUpdate failed: %08x\n", GetLastError());
2214 SetLastError(0xdeadbeef);
2215 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2216 &envelopedInfo, NULL, &streamInfo);
2219 broken(!msg), /* Win9x */
2220 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2223 SetLastError(0xdeadbeef);
2224 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2226 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2227 SetLastError(0xdeadbeef);
2228 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2230 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2233 SetLastError(0xdeadbeef);
2234 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2235 &envelopedInfo, NULL, &streamInfo);
2238 broken(!msg), /* Win9x */
2239 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2242 SetLastError(0xdeadbeef);
2243 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2245 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2246 SetLastError(0xdeadbeef);
2247 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2250 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2251 "CryptMsgUpdate failed: %08x\n", GetLastError());
2256 static const BYTE envelopedEmptyBareContent[] = {
2257 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2258 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2259 0x03,0x04,0x05,0x00,0x80,0x00 };
2260 static const BYTE envelopedEmptyContent[] = {
2261 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24,
2262 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2263 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2264 0x03,0x04,0x05,0x00,0x80,0x00 };
2266 static void test_enveloped_msg_encoding(void)
2269 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2270 { oid_rsa_rc4, { 0, NULL } }, NULL };
2272 SetLastError(0xdeadbeef);
2273 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2274 &envelopedInfo, NULL, NULL);
2277 broken(!msg), /* Win9x */
2278 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2281 check_param("enveloped empty bare content", msg,
2282 CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent,
2283 sizeof(envelopedEmptyBareContent));
2284 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
2285 envelopedEmptyContent, sizeof(envelopedEmptyContent));
2290 static void test_enveloped_msg(void)
2292 test_enveloped_msg_open();
2293 test_enveloped_msg_update();
2294 test_enveloped_msg_encoding();
2297 static CRYPT_DATA_BLOB b4 = { 0, NULL };
2298 static const struct update_accum a4 = { 1, &b4 };
2300 static const BYTE bogusOIDContent[] = {
2301 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2303 static const BYTE bogusHashContent[] = {
2304 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2305 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2306 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2307 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2308 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2309 static const BYTE envelopedBareContentWithoutData[] = {
2310 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2311 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2312 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2313 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2314 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b,
2315 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f,
2316 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94,
2317 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72,
2318 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18,
2319 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3,
2320 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6,
2321 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49,
2322 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e,
2323 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2324 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 };
2326 static void test_decode_msg_update(void)
2330 CMSG_STREAM_INFO streamInfo = { 0 };
2332 struct update_accum accum = { 0, NULL };
2334 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2335 /* Update with a full message in a final update */
2336 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2337 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2338 /* Can't update after a final update */
2339 SetLastError(0xdeadbeef);
2340 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2341 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2342 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2345 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2346 /* Can't send a non-final update without streaming */
2347 SetLastError(0xdeadbeef);
2348 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2350 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2351 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2352 /* A subsequent final update succeeds */
2353 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2354 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2359 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2360 /* Updating a message that has a NULL stream callback fails */
2361 SetLastError(0xdeadbeef);
2362 /* Crashes on some Win9x */
2363 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2366 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2367 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2368 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2370 /* Changing the callback pointer after the fact yields the same error (so
2371 * the message must copy the stream info, not just store a pointer to it)
2373 streamInfo.pfnStreamOutput = nop_stream_output;
2374 SetLastError(0xdeadbeef);
2375 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2378 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2379 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2380 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2385 /* Empty non-final updates are allowed when streaming.. */
2386 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2387 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2388 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2389 /* but final updates aren't when not enough data has been received. */
2390 SetLastError(0xdeadbeef);
2391 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2393 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2394 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2397 /* Updating the message byte by byte is legal */
2398 streamInfo.pfnStreamOutput = accumulating_stream_output;
2399 streamInfo.pvArg = &accum;
2400 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2401 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2402 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2403 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2404 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2405 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2408 check_updates("byte-by-byte empty content", &a4, &accum);
2409 free_updates(&accum);
2411 /* Decoding bogus content fails in non-streaming mode.. */
2412 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2413 SetLastError(0xdeadbeef);
2414 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2415 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2416 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2417 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2420 /* and as the final update in streaming mode.. */
2421 streamInfo.pfnStreamOutput = nop_stream_output;
2422 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2423 SetLastError(0xdeadbeef);
2424 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2425 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2426 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2427 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2430 /* and even as a non-final update in streaming mode. */
2431 streamInfo.pfnStreamOutput = nop_stream_output;
2432 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2433 SetLastError(0xdeadbeef);
2434 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
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",
2442 /* An empty message can be opened with undetermined type.. */
2443 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2444 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2446 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2448 /* but decoding it as an explicitly typed message fails. */
2449 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2451 SetLastError(0xdeadbeef);
2452 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2454 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2455 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2456 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2459 /* On the other hand, decoding the bare content of an empty message fails
2460 * with unspecified type..
2462 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2463 SetLastError(0xdeadbeef);
2464 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2465 sizeof(dataEmptyBareContent), TRUE);
2466 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2467 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2468 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2471 /* but succeeds with explicit type. */
2472 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2474 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2475 sizeof(dataEmptyBareContent), TRUE);
2476 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2479 /* Decoding valid content with an unsupported OID fails */
2480 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2481 SetLastError(0xdeadbeef);
2482 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2483 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2484 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2487 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2488 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2489 SetLastError(0xdeadbeef);
2490 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2491 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2492 "CryptMsgUpdate failed: %08x\n", GetLastError());
2494 /* while with specified type it fails. */
2495 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2497 SetLastError(0xdeadbeef);
2498 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2499 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2500 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2501 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2502 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2505 /* On the other hand, decoding the bare content of an empty hash message
2506 * fails with unspecified type..
2508 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2509 SetLastError(0xdeadbeef);
2510 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2511 sizeof(hashEmptyBareContent), TRUE);
2512 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2513 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2514 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2515 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2518 /* but succeeds with explicit type. */
2519 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2521 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2522 sizeof(hashEmptyBareContent), TRUE);
2523 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2524 "CryptMsgUpdate failed: %x\n", GetLastError());
2527 /* And again, opening a (non-empty) hash message with unspecified type
2530 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2531 SetLastError(0xdeadbeef);
2532 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2533 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2535 /* while with specified type it fails.. */
2536 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2538 SetLastError(0xdeadbeef);
2539 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2540 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2541 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2542 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2543 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2546 /* and decoding the bare content of a non-empty hash message fails with
2547 * unspecified type..
2549 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2550 SetLastError(0xdeadbeef);
2551 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2552 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2553 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2554 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2555 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2558 /* but succeeds with explicit type. */
2559 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2561 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2562 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2565 /* Opening a (non-empty) hash message with unspecified type and a bogus
2566 * hash value succeeds..
2568 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2569 SetLastError(0xdeadbeef);
2570 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2571 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2574 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2575 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2576 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2578 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2579 SetLastError(0xdeadbeef);
2580 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2581 sizeof(signedWithCertAndCrlBareContent), TRUE);
2582 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2583 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2584 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2587 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2589 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2590 sizeof(signedWithCertAndCrlBareContent), TRUE);
2591 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2594 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2596 /* The first update succeeds.. */
2597 ret = CryptMsgUpdate(msg, detachedSignedContent,
2598 sizeof(detachedSignedContent), TRUE);
2599 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2600 /* as does a second (probably to update the detached portion).. */
2601 ret = CryptMsgUpdate(msg, detachedSignedContent,
2602 sizeof(detachedSignedContent), TRUE);
2603 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2604 /* while a third fails. */
2605 ret = CryptMsgUpdate(msg, detachedSignedContent,
2606 sizeof(detachedSignedContent), TRUE);
2607 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2608 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2611 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2612 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2613 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2614 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2615 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2616 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2617 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2618 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2619 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2621 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2622 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2623 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2626 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2628 SetLastError(0xdeadbeef);
2629 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2630 sizeof(envelopedEmptyBareContent), TRUE);
2631 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2634 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2636 SetLastError(0xdeadbeef);
2637 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2638 sizeof(envelopedEmptyContent), TRUE);
2641 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2642 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2643 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2646 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2647 SetLastError(0xdeadbeef);
2648 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2649 sizeof(envelopedEmptyBareContent), TRUE);
2651 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2652 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2653 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2656 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2657 SetLastError(0xdeadbeef);
2658 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2659 sizeof(envelopedEmptyContent), TRUE);
2660 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2663 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2665 SetLastError(0xdeadbeef);
2666 ret = CryptMsgUpdate(msg, envelopedBareContentWithoutData,
2667 sizeof(envelopedBareContentWithoutData), TRUE);
2668 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2672 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2673 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2675 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2676 const CMSG_SIGNER_INFO *expected)
2678 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2679 expected->dwVersion, got->dwVersion);
2680 ok(got->Issuer.cbData == expected->Issuer.cbData,
2681 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2682 got->Issuer.cbData);
2683 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2684 "Unexpected issuer\n");
2685 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2686 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2687 got->SerialNumber.cbData);
2688 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2689 got->SerialNumber.cbData), "Unexpected serial number\n");
2690 /* FIXME: check more things */
2693 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2694 const CMSG_CMS_SIGNER_INFO *expected)
2696 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2697 expected->dwVersion, got->dwVersion);
2698 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2699 "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2700 got->SignerId.dwIdChoice);
2701 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2703 if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2705 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2706 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2707 "Expected issuer size %d, got %d\n",
2708 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2709 U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2710 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2711 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2712 U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2713 "Unexpected issuer\n");
2714 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2715 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2716 "Expected serial number size %d, got %d\n",
2717 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2718 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2719 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2720 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2721 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2722 "Unexpected serial number\n");
2726 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2727 "expected key id size %d, got %d\n",
2728 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2729 ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2730 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2731 "unexpected key id\n");
2734 /* FIXME: check more things */
2737 static const BYTE signedWithCertAndCrlComputedHash[] = {
2738 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2740 static BYTE keyIdIssuer[] = {
2741 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2742 0x0a,0x07,0x01,0x04,0x01,0x01 };
2743 static const BYTE publicPrivateKeyPair[] = {
2744 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00,
2745 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b,
2746 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50,
2747 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54,
2748 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39,
2749 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7,
2750 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48,
2751 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17,
2752 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54,
2753 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33,
2754 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52,
2755 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e,
2756 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61,
2757 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb,
2758 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02,
2759 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90,
2760 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e,
2761 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce,
2762 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14,
2763 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5,
2764 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5,
2765 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94,
2766 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68,
2767 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71,
2768 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25,
2769 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc,
2770 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a,
2771 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64,
2772 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77,
2773 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68,
2774 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab,
2775 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9,
2776 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed,
2777 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01,
2778 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e,
2779 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71,
2780 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0,
2781 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87,
2782 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b,
2783 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e };
2784 static const BYTE envelopedMessage[] = {
2785 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,
2786 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,
2787 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,
2788 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,
2789 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
2790 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65,
2791 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae,
2792 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1,
2793 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51,
2794 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf,
2795 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b,
2796 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e,
2797 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e,
2798 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70,
2799 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,
2800 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,
2801 0x04,0x5f,0x80,0xf2,0x17 };
2802 static const BYTE envelopedBareMessage[] = {
2803 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2804 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2805 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2806 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2807 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d,
2808 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d,
2809 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5,
2810 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e,
2811 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2,
2812 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4,
2813 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70,
2814 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c,
2815 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55,
2816 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2817 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c,
2819 static const BYTE envelopedMessageWith3Recps[] = {
2820 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,
2821 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e,
2822 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,
2823 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,
2824 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,
2825 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e,
2826 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba,
2827 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f,
2828 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5,
2829 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21,
2830 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae,
2831 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0,
2832 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96,
2833 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae,
2834 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,
2835 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,
2836 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6,
2837 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
2838 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf,
2839 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9,
2840 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3,
2841 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02,
2842 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70,
2843 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3,
2844 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74,
2845 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94,
2846 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7,
2847 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,
2848 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,
2849 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
2850 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98,
2851 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5,
2852 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9,
2853 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3,
2854 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8,
2855 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac,
2856 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc,
2857 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5,
2858 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1,
2859 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
2860 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,
2861 0x80,0x04,0x4e,0x99,0x9d,0x4c };
2862 static const BYTE serialNumber[] = {
2863 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2,
2865 static const BYTE issuer[] = {
2866 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 };
2868 static void test_decode_msg_get_param(void)
2871 HCRYPTPROV hCryptProv;
2874 DWORD size = 0, value;
2876 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2878 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2879 SetLastError(0xdeadbeef);
2880 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2881 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2882 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2883 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2884 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2888 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2889 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2892 /* Crashes on some Win9x */
2893 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2894 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2895 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2896 emptyHashParam, sizeof(emptyHashParam));
2899 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2900 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2901 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2903 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2905 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2906 hashParam, sizeof(hashParam));
2907 /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2908 * even though there's only one hash.
2910 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2911 ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2912 "CryptMsgGetParam failed: %08x\n", GetLastError());
2914 buf = CryptMemAlloc(size);
2919 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2920 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2921 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2924 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2925 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2926 value = CMSG_HASHED_DATA_V0;
2927 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2931 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2932 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2933 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2934 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2936 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2937 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2938 size = sizeof(value);
2940 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2941 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2942 ok(value == 1, "Expected 1 signer, got %d\n", value);
2944 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2945 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2946 "CryptMsgGetParam failed: %08x\n", GetLastError());
2948 buf = CryptMemAlloc(size);
2953 CMSG_SIGNER_INFO signer = { 0 };
2955 signer.dwVersion = 1;
2956 signer.Issuer.cbData = sizeof(encodedCommonName);
2957 signer.Issuer.pbData = encodedCommonName;
2958 signer.SerialNumber.cbData = sizeof(serialNum);
2959 signer.SerialNumber.pbData = serialNum;
2960 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2961 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2962 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2965 /* Getting the CMS signer info of a PKCS7 message is possible. */
2967 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2968 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2969 "CryptMsgGetParam failed: %08x\n", GetLastError());
2971 buf = CryptMemAlloc(size);
2976 CMSG_CMS_SIGNER_INFO signer = { 0 };
2978 signer.dwVersion = 1;
2979 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2980 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2981 sizeof(encodedCommonName);
2982 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2983 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2985 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2986 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2987 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2988 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2991 /* index is ignored when getting signer count */
2992 size = sizeof(value);
2993 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2994 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2995 ok(value == 1, "Expected 1 signer, got %d\n", value);
2996 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2997 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2998 ok(value == 0, "Expected 0 certs, got %d\n", value);
2999 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
3000 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3001 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
3003 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3005 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
3006 sizeof(signedWithCertAndCrlBareContent), TRUE);
3007 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3008 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
3009 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3010 ok(value == 1, "Expected 1 cert, got %d\n", value);
3011 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
3012 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
3013 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3014 ok(value == 1, "Expected 1 CRL, got %d\n", value);
3015 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
3016 check_param("signed with cert and CRL computed hash", msg,
3017 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
3018 sizeof(signedWithCertAndCrlComputedHash));
3021 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3022 ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
3023 sizeof(signedKeyIdEmptyContent), TRUE);
3024 if (!ret && GetLastError() == OSS_DATA_ERROR)
3027 win_skip("Subsequent tests crash on some Win9x\n");
3030 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3031 size = sizeof(value);
3032 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
3033 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3034 ok(value == 1, "Expected 1 signer, got %d\n", value);
3035 /* Getting the regular (non-CMS) signer info from a CMS message is also
3039 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
3040 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3042 buf = CryptMemAlloc(size);
3047 CMSG_SIGNER_INFO signer;
3050 /* and here's the little oddity: for a CMS message using the key id
3051 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
3052 * a signer with a zero (not empty) serial number, and whose issuer is
3053 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
3054 * and value of the key id.
3056 signer.dwVersion = CMSG_SIGNED_DATA_V3;
3057 signer.Issuer.cbData = sizeof(keyIdIssuer);
3058 signer.Issuer.pbData = keyIdIssuer;
3059 signer.SerialNumber.cbData = 1;
3060 signer.SerialNumber.pbData = &zero;
3061 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
3062 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
3066 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
3067 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3069 buf = CryptMemAlloc(size);
3074 CMSG_CMS_SIGNER_INFO signer = { 0 };
3076 signer.dwVersion = CMSG_SIGNED_DATA_V3;
3077 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
3078 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
3079 U(signer.SignerId).KeyId.pbData = serialNum;
3080 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3081 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
3082 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
3087 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3089 CryptMsgUpdate(msg, envelopedEmptyBareContent,
3090 sizeof(envelopedEmptyBareContent), TRUE);
3092 check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL,
3096 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3097 CryptMsgUpdate(msg, envelopedEmptyContent, sizeof(envelopedEmptyContent),
3100 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0);
3103 pCryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL,
3104 CRYPT_VERIFYCONTEXT);
3105 SetLastError(0xdeadbeef);
3106 ret = CryptImportKey(hCryptProv, publicPrivateKeyPair,
3107 sizeof(publicPrivateKeyPair), 0, 0, &key);
3109 broken(!ret && GetLastError() == NTE_PERM), /* WinME and some NT4 */
3110 "CryptImportKey failed: %08x\n", GetLastError());
3112 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3113 CryptMsgUpdate(msg, envelopedMessage, sizeof(envelopedMessage), TRUE);
3115 check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM,
3116 envelopedMessage + sizeof(envelopedMessage) - 4, 4);
3119 decryptPara.hCryptProv = hCryptProv;
3120 SetLastError(0xdeadbeef);
3121 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3123 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3124 decryptPara.hCryptProv = 0;
3125 SetLastError(0xdeadbeef);
3126 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3128 ok(!ret && GetLastError() == CRYPT_E_ALREADY_DECRYPTED,
3129 "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError());
3131 check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData,
3135 win_skip("failed to import a key, skipping tests\n");
3138 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3140 CryptMsgUpdate(msg, envelopedBareMessage, sizeof(envelopedBareMessage),
3143 check_param("enveloped bare message before decrypting", msg,
3144 CMSG_CONTENT_PARAM, envelopedBareMessage +
3145 sizeof(envelopedBareMessage) - 4, 4);
3148 decryptPara.hCryptProv = hCryptProv;
3149 SetLastError(0xdeadbeef);
3150 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3152 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3154 check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData,
3158 win_skip("failed to import a key, skipping tests\n");
3162 CryptDestroyKey(key);
3163 CryptReleaseContext(hCryptProv, 0);
3165 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3166 CryptMsgUpdate(msg, envelopedMessageWith3Recps,
3167 sizeof(envelopedMessageWith3Recps), TRUE);
3170 check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM,
3171 (const BYTE *)&value, sizeof(value));
3173 SetLastError(0xdeadbeef);
3174 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 3, NULL, &size);
3176 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3177 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3179 SetLastError(0xdeadbeef);
3180 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, NULL, &size);
3182 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3184 ok(size >= 142, "unexpected size: %u\n", size);
3186 buf = CryptMemAlloc(size);
3191 CERT_INFO *certInfo = (CERT_INFO *)buf;
3193 SetLastError(0xdeadbeef);
3194 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, buf, &size);
3196 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3198 ok(certInfo->SerialNumber.cbData == sizeof(serialNumber),
3199 "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData);
3201 ok(!memcmp(certInfo->SerialNumber.pbData, serialNumber,
3202 sizeof(serialNumber)), "unexpected serial number\n");
3204 ok(certInfo->Issuer.cbData == sizeof(issuer),
3205 "unexpected issuer size: %u\n", certInfo->Issuer.cbData);
3207 ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)),
3208 "unexpected issuer\n");
3214 static void test_decode_msg(void)
3216 test_decode_msg_update();
3217 test_decode_msg_get_param();
3220 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
3221 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
3222 static BYTE encodedPubKey[] = {
3223 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
3224 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
3226 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
3227 static BYTE mod_encoded[] = {
3228 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
3231 static void test_msg_control(void)
3233 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3237 CERT_INFO certInfo = { 0 };
3238 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
3239 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
3240 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
3243 ret = CryptMsgControl(NULL, 0, 0, NULL);
3246 /* Data encode messages don't allow any sort of control.. */
3247 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
3249 /* either with no prior update.. */
3250 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3252 SetLastError(0xdeadbeef);
3253 ret = CryptMsgControl(msg, 0, i, NULL);
3254 ok(!ret && GetLastError() == E_INVALIDARG,
3255 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3257 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3258 /* or after an update. */
3259 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3261 SetLastError(0xdeadbeef);
3262 ret = CryptMsgControl(msg, 0, i, NULL);
3263 ok(!ret && GetLastError() == E_INVALIDARG,
3264 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3268 /* Hash encode messages don't allow any sort of control.. */
3269 hashInfo.cbSize = sizeof(hashInfo);
3270 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
3271 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
3273 /* either with no prior update.. */
3274 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3276 SetLastError(0xdeadbeef);
3277 ret = CryptMsgControl(msg, 0, i, NULL);
3278 ok(!ret && GetLastError() == E_INVALIDARG,
3279 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3281 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3282 /* or after an update. */
3283 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3285 SetLastError(0xdeadbeef);
3286 ret = CryptMsgControl(msg, 0, i, NULL);
3287 ok(!ret && GetLastError() == E_INVALIDARG,
3288 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3292 /* Signed encode messages likewise don't allow any sort of control.. */
3293 signInfo.cbSize = sizeof(signInfo);
3294 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
3296 /* either before an update.. */
3297 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3299 SetLastError(0xdeadbeef);
3300 ret = CryptMsgControl(msg, 0, i, NULL);
3301 ok(!ret && GetLastError() == E_INVALIDARG,
3302 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3304 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3305 /* or after an update. */
3306 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3308 SetLastError(0xdeadbeef);
3309 ret = CryptMsgControl(msg, 0, i, NULL);
3310 ok(!ret && GetLastError() == E_INVALIDARG,
3311 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3315 /* Decode messages behave a bit differently. */
3316 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3317 /* Bad control type */
3318 SetLastError(0xdeadbeef);
3319 ret = CryptMsgControl(msg, 0, 0, NULL);
3320 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3321 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3322 SetLastError(0xdeadbeef);
3323 ret = CryptMsgControl(msg, 1, 0, NULL);
3324 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3325 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3326 /* Can't verify the hash of an indeterminate-type message */
3327 SetLastError(0xdeadbeef);
3328 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3329 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3330 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3332 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
3334 /* Can't decrypt an indeterminate-type message */
3335 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3336 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3337 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3342 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3344 /* Can't verify the hash of an empty message */
3345 SetLastError(0xdeadbeef);
3346 /* Crashes on some Win9x */
3347 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3349 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3350 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3352 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3354 /* Can't verify the signature of a hash message */
3355 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3356 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3357 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3358 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
3360 /* Oddly enough, this fails, crashes on some Win9x */
3361 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3362 ok(!ret, "Expected failure\n");
3365 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3367 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
3368 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3369 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3370 /* Can't decrypt an indeterminate-type message */
3371 SetLastError(0xdeadbeef);
3372 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3373 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3374 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3377 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3379 /* Can't verify the hash of a detached message before it's been updated. */
3380 SetLastError(0xdeadbeef);
3381 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3382 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3383 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3384 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3386 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3387 /* Still can't verify the hash of a detached message with the content
3388 * of the detached hash given..
3390 SetLastError(0xdeadbeef);
3391 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3392 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
3393 "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
3394 /* and giving the content of the message after attempting to verify the
3397 SetLastError(0xdeadbeef);
3398 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3401 (GetLastError() == NTE_BAD_HASH_STATE ||
3402 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3403 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
3404 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3405 "got %08x\n", GetLastError());
3408 /* Finally, verifying the hash of a detached message in the correct order:
3409 * 1. Update with the detached hash message
3410 * 2. Update with the content of the message
3411 * 3. Verifying the hash of the message
3414 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3416 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3418 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3419 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3420 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3421 SetLastError(0xdeadbeef);
3422 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3423 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3426 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3428 /* Can't verify the hash of a signed message */
3429 SetLastError(0xdeadbeef);
3430 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3431 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3432 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3433 /* Can't decrypt a signed message */
3434 SetLastError(0xdeadbeef);
3435 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3436 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3437 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3439 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3440 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3442 CryptMsgUpdate(msg, signedWithCertBareContent,
3443 sizeof(signedWithCertBareContent), TRUE);
3444 /* With an empty cert info, the signer can't be found in the message (and
3445 * the signature can't be verified.
3447 SetLastError(0xdeadbeef);
3448 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3449 ok(!ret && (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND ||
3450 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3451 "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n",
3453 /* The cert info is expected to have an issuer, serial number, and public
3456 certInfo.SerialNumber.cbData = sizeof(serialNum);
3457 certInfo.SerialNumber.pbData = serialNum;
3458 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3459 certInfo.Issuer.pbData = encodedCommonName;
3460 SetLastError(0xdeadbeef);
3461 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3462 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3463 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3464 "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError());
3466 /* This cert has a public key, but it's not in a usable form */
3467 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3469 ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
3470 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
3473 /* Crashes on some Win9x */
3474 /* Again, cert info needs to have a public key set */
3475 SetLastError(0xdeadbeef);
3476 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3478 (GetLastError() == CRYPT_E_ASN1_EOD ||
3479 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3480 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3481 /* The public key is supposed to be in encoded form.. */
3482 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3483 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3484 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
3485 SetLastError(0xdeadbeef);
3486 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3488 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3489 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3490 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3491 /* but not as a X509_PUBLIC_KEY_INFO.. */
3492 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3493 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
3494 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
3495 SetLastError(0xdeadbeef);
3496 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3498 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3499 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3500 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3501 /* This decodes successfully, but it doesn't match any key in the message */
3502 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
3503 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
3504 SetLastError(0xdeadbeef);
3505 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3506 /* In Wine's rsaenh, this fails to decode because the key length is too
3507 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
3512 (GetLastError() == NTE_BAD_SIGNATURE ||
3513 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3514 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3517 /* A message with no data doesn't have a valid signature */
3518 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3519 ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
3520 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
3523 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3524 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
3525 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
3526 SetLastError(0xdeadbeef);
3527 /* Crashes on some Win9x */
3528 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3530 (GetLastError() == NTE_BAD_SIGNATURE ||
3531 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3532 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3535 /* Finally, this succeeds */
3536 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3537 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3538 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3539 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3540 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3541 "CryptMsgControl failed: %08x\n", GetLastError());
3544 /* Test verifying signature of a detached signed message */
3545 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3547 ret = CryptMsgUpdate(msg, detachedSignedContent,
3548 sizeof(detachedSignedContent), TRUE);
3549 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3550 /* Can't verify the sig without having updated the data */
3551 SetLastError(0xdeadbeef);
3552 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3553 ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
3554 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3555 "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n",
3557 /* Now that the signature's been checked, can't do the final update */
3558 SetLastError(0xdeadbeef);
3559 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3562 (GetLastError() == NTE_BAD_HASH_STATE ||
3563 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3564 GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */
3565 broken(ret), /* Win9x */
3566 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3567 "got %08x\n", GetLastError());
3569 /* Updating with the detached portion of the message and the data of the
3570 * the message allows the sig to be verified.
3572 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3574 ret = CryptMsgUpdate(msg, detachedSignedContent,
3575 sizeof(detachedSignedContent), TRUE);
3576 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3577 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3578 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3579 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3580 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3581 "CryptMsgControl failed: %08x\n", GetLastError());
3584 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3586 decryptPara.cbSize = 0;
3587 SetLastError(0xdeadbeef);
3588 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3590 ok(!ret && GetLastError() == E_INVALIDARG,
3591 "expected E_INVALIDARG, got %08x\n", GetLastError());
3592 decryptPara.cbSize = sizeof(decryptPara);
3595 SetLastError(0xdeadbeef);
3596 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3597 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3598 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3600 SetLastError(0xdeadbeef);
3601 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
3602 sizeof(envelopedEmptyBareContent), TRUE);
3603 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3604 SetLastError(0xdeadbeef);
3605 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3607 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3608 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3611 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3613 SetLastError(0xdeadbeef);
3614 ret = CryptMsgUpdate(msg, envelopedBareMessage,
3615 sizeof(envelopedBareMessage), TRUE);
3616 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3617 SetLastError(0xdeadbeef);
3618 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3620 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
3621 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
3625 /* win9x has much less parameter checks and will crash on many tests
3626 * this code is from test_signed_msg_update()
3628 static BOOL detect_nt(void)
3631 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
3632 CERT_INFO certInfo = { 0 };
3634 if (!pCryptAcquireContextW)
3637 certInfo.SerialNumber.cbData = sizeof(serialNum);
3638 certInfo.SerialNumber.pbData = serialNum;
3639 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3640 certInfo.Issuer.pbData = encodedCommonName;
3641 signer.pCertInfo = &certInfo;
3642 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3644 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3645 PROV_RSA_FULL, CRYPT_NEWKEYSET);
3646 if (!ret && GetLastError() == NTE_EXISTS) {
3647 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3651 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
3654 CryptReleaseContext(signer.hCryptProv, 0);
3655 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
3656 CRYPT_DELETEKEYSET);
3661 static void test_msg_get_and_verify_signer(void)
3665 PCCERT_CONTEXT signer;
3672 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
3673 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3676 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3677 /* An empty message has no signer */
3678 SetLastError(0xdeadbeef);
3679 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3680 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3681 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3682 /* The signer is cleared on error */
3683 signer = (PCCERT_CONTEXT)0xdeadbeef;
3684 SetLastError(0xdeadbeef);
3685 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3686 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3687 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3688 ok(!signer, "expected signer to be NULL\n");
3689 /* The signer index is also cleared on error */
3690 signerIndex = 0xdeadbeef;
3691 SetLastError(0xdeadbeef);
3692 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3693 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3694 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3695 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
3696 /* An unsigned message (msgData isn't a signed message at all)
3697 * likewise has no signer.
3699 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3700 SetLastError(0xdeadbeef);
3701 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3702 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3703 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3706 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3707 /* A "signed" message created with no signer cert likewise has no signer */
3708 ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
3711 /* Crashes on most Win9x */
3712 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3713 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3714 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3718 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3719 /* A signed message succeeds, .. */
3720 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3721 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3722 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3723 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3724 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3725 /* the signer index can be retrieved, .. */
3726 signerIndex = 0xdeadbeef;
3727 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3728 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3729 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3731 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
3732 /* as can the signer cert. */
3733 signer = (PCCERT_CONTEXT)0xdeadbeef;
3734 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3735 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3736 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3738 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3739 "expected a valid signer\n");
3740 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3741 CertFreeCertificateContext(signer);
3742 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3744 signerIndex = 0xdeadbeef;
3745 SetLastError(0xdeadbeef);
3746 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3747 NULL, &signerIndex);
3748 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3749 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3750 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3751 * message signer not to be found.
3753 SetLastError(0xdeadbeef);
3754 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3756 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3757 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3758 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3759 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3760 * the message signer not to be found.
3762 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3763 CERT_STORE_CREATE_NEW_FLAG, NULL);
3764 SetLastError(0xdeadbeef);
3765 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3767 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3768 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3769 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3770 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3771 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3772 CERT_STORE_ADD_ALWAYS, NULL);
3773 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win98 */),
3774 "CertAddEncodedCertificateToStore failed: 0x%08x\n", GetLastError());
3775 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3776 * the signer succeeds.
3778 SetLastError(0xdeadbeef);
3779 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3781 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3782 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3783 CertCloseStore(store, 0);
3789 init_function_pointers();
3790 have_nt = detect_nt();
3792 win_skip("Win9x crashes on some parameter checks\n");
3794 /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
3795 if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
3797 win_skip("Some tests will crash on older crypt32 implementations\n");
3801 /* Basic parameter checking tests */
3802 test_msg_open_to_encode();
3803 test_msg_open_to_decode();
3804 test_msg_get_param();
3808 /* Message-type specific tests */
3812 test_enveloped_msg();
3815 test_msg_get_and_verify_signer();