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