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"
33 static char oid_rsa_md5[] = szOID_RSA_MD5;
35 static BOOL (WINAPI * pCryptAcquireContextA)
36 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
37 static BOOL (WINAPI * pCryptAcquireContextW)
38 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
40 static void init_function_pointers(void)
42 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
44 #define GET_PROC(dll, func) \
45 p ## func = (void *)GetProcAddress(dll, #func); \
47 trace("GetProcAddress(%s) failed\n", #func);
49 GET_PROC(hAdvapi32, CryptAcquireContextA)
50 GET_PROC(hAdvapi32, CryptAcquireContextW)
55 static void test_msg_open_to_encode(void)
60 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
62 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
64 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
69 SetLastError(0xdeadbeef);
70 msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
71 ok(!msg && GetLastError() == E_INVALIDARG,
72 "Expected E_INVALIDARG, got %x\n", GetLastError());
73 SetLastError(0xdeadbeef);
74 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
75 ok(!msg && GetLastError() == E_INVALIDARG,
76 "Expected E_INVALIDARG, got %x\n", GetLastError());
78 /* Bad message types */
79 SetLastError(0xdeadbeef);
80 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
81 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
82 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
83 SetLastError(0xdeadbeef);
84 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
86 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
87 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
88 SetLastError(0xdeadbeef);
89 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
90 CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
91 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
92 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
93 SetLastError(0xdeadbeef);
94 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
96 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
97 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
100 static void test_msg_open_to_decode(void)
103 CMSG_STREAM_INFO streamInfo = { 0 };
105 SetLastError(0xdeadbeef);
106 msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
107 ok(!msg && GetLastError() == E_INVALIDARG,
108 "Expected E_INVALIDARG, got %x\n", GetLastError());
111 SetLastError(0xdeadbeef);
112 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
113 ok(!msg && GetLastError() == E_INVALIDARG,
114 "Expected E_INVALIDARG, got %x\n", GetLastError());
115 SetLastError(0xdeadbeef);
116 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
117 ok(!msg && GetLastError() == E_INVALIDARG,
118 "Expected E_INVALIDARG, got %x\n", GetLastError());
120 /* The message type can be explicit... */
121 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
123 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
125 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
127 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
129 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
131 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
133 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
135 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
137 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
138 CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
139 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
142 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
143 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
145 /* or even invalid. */
146 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
148 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
150 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
151 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
154 /* And even though the stream info parameter "must be set to NULL" for
155 * CMSG_HASHED, it's still accepted.
157 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
159 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
163 static void test_msg_get_param(void)
167 DWORD size, i, value;
168 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
169 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
172 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
173 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
174 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
177 /* Decoded messages */
178 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
179 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
180 /* For decoded messages, the type is always available */
182 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
183 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
184 size = sizeof(value);
185 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
186 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
187 /* For this (empty) message, the type isn't set */
188 ok(value == 0, "Expected type 0, got %d\n", value);
191 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
193 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
194 /* For explicitly typed messages, the type is known. */
195 size = sizeof(value);
196 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
197 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
198 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
199 for (i = CMSG_CONTENT_PARAM; have_nt && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
202 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
203 ok(!ret, "Parameter %d: expected failure\n", i);
207 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
209 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
210 size = sizeof(value);
211 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
212 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
213 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
214 for (i = CMSG_CONTENT_PARAM; have_nt && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
217 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
218 ok(!ret, "Parameter %d: expected failure\n", i);
222 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
224 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
225 size = sizeof(value);
226 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
227 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
228 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
229 for (i = CMSG_CONTENT_PARAM; have_nt && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
232 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
233 ok(!ret, "Parameter %d: expected failure\n", i);
237 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
239 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
240 size = sizeof(value);
241 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
242 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
243 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
244 for (i = CMSG_CONTENT_PARAM; have_nt && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
247 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
248 ok(!ret, "Parameter %d: expected failure\n", i);
252 /* Explicitly typed messages get their types set, even if they're invalid */
253 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
255 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
256 size = sizeof(value);
257 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
258 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
259 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
262 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
263 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
264 size = sizeof(value);
265 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
266 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
267 ok(value == 1000, "Expected 1000, got %d\n", value);
271 static void test_msg_close(void)
276 /* NULL succeeds.. */
277 ret = CryptMsgClose(NULL);
278 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
279 /* but an arbitrary pointer crashes. */
281 ret = CryptMsgClose((HCRYPTMSG)1);
282 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
284 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
285 ret = CryptMsgClose(msg);
286 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
289 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
290 const BYTE *expected, DWORD expectedSize)
297 ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
298 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */ ||
299 GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x, for some params */),
300 "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
303 win_skip("parameter %d not supported, skipping tests\n", param);
306 buf = HeapAlloc(GetProcessHeap(), 0, size);
307 ret = CryptMsgGetParam(msg, param, 0, buf, &size);
308 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
309 ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
311 if (size == expectedSize && size)
312 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
313 HeapFree(GetProcessHeap(), 0, buf);
316 static void test_data_msg_open(void)
319 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
320 CMSG_STREAM_INFO streamInfo = { 0 };
321 char oid[] = "1.2.3";
323 /* The data message type takes no additional info */
324 SetLastError(0xdeadbeef);
325 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
327 ok(!msg && GetLastError() == E_INVALIDARG,
328 "Expected E_INVALIDARG, got %x\n", GetLastError());
329 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
331 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
334 /* An empty stream info is allowed. */
335 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
337 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
340 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
341 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
343 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
345 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
346 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
347 CMSG_DATA, NULL, oid, NULL);
348 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
350 /* and when a stream info is given, even though you're not supposed to be
351 * able to use anything but szOID_RSA_data when streaming is being used.
353 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
354 CMSG_DATA, NULL, oid, &streamInfo);
355 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
359 static const BYTE msgData[] = { 1, 2, 3, 4 };
361 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
367 static void test_data_msg_update(void)
371 CMSG_STREAM_INFO streamInfo = { 0 };
373 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
375 /* Can't update a message that wasn't opened detached with final = FALSE */
376 SetLastError(0xdeadbeef);
377 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
378 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
379 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
380 /* Updating it with final = TRUE succeeds */
381 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
382 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
383 /* Any subsequent update will fail, as the last was final */
384 SetLastError(0xdeadbeef);
385 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
386 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
387 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
390 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
392 /* Can't update a message with no data */
393 SetLastError(0xdeadbeef);
394 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
395 /* This test returns FALSE on XP and earlier but TRUE on Vista, so can't be tested.
396 * GetLastError is either E_INVALIDARG (NT) or unset (9x/Vista), so it doesn't
397 * make sense to test this.
400 /* Curiously, a valid update will now fail as well, presumably because of
401 * the last (invalid, but final) update.
403 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
404 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
405 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
408 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
409 CMSG_DATA, NULL, NULL, NULL);
412 /* Doesn't appear to be able to update CMSG-DATA with non-final updates.
413 * On Win9x, this sometimes succeeds, sometimes fails with
414 * GetLastError() == 0, so it's not worth checking there.
416 SetLastError(0xdeadbeef);
417 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
418 ok(!ret && GetLastError() == E_INVALIDARG,
419 "Expected E_INVALIDARG, got %x\n", GetLastError());
420 SetLastError(0xdeadbeef);
421 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
422 ok(!ret && GetLastError() == E_INVALIDARG,
423 "Expected E_INVALIDARG, got %x\n", GetLastError());
426 skip("not updating CMSG_DATA with a non-final update\n");
427 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
428 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
433 /* Calling update after opening with an empty stream info (with a bogus
434 * output function) yields an error:
436 /* Crashes on some Win9x */
437 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
439 SetLastError(0xdeadbeef);
440 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
441 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
442 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
443 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
447 /* Calling update with a valid output function succeeds, even if the data
448 * exceeds the size specified in the stream info.
450 streamInfo.pfnStreamOutput = nop_stream_output;
451 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
453 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
454 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
455 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
456 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
460 static void test_data_msg_get_param(void)
465 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
467 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
470 /* Content and bare content are always gettable when not streaming */
472 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
473 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
475 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
476 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
477 /* But for this type of message, the signer and hash aren't applicable,
478 * and the type isn't available.
481 SetLastError(0xdeadbeef);
482 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
483 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
484 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
485 SetLastError(0xdeadbeef);
486 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
487 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
488 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
489 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
490 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
491 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
494 /* Can't get content or bare content when streaming */
495 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
497 SetLastError(0xdeadbeef);
498 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
499 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
500 "Expected E_INVALIDARG, got %x\n", GetLastError());
501 SetLastError(0xdeadbeef);
502 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
503 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
504 "Expected E_INVALIDARG, got %x\n", GetLastError());
508 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
509 static const BYTE dataEmptyContent[] = {
510 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
512 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
513 static const BYTE dataContent[] = {
514 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
515 0x04,0x04,0x01,0x02,0x03,0x04 };
520 CRYPT_DATA_BLOB *updates;
523 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
524 DWORD cb, BOOL final)
526 struct update_accum *accum = (struct update_accum *)pvArg;
530 accum->updates = CryptMemRealloc(accum->updates,
531 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
533 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
536 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
538 blob->pbData = CryptMemAlloc(cb);
541 memcpy(blob->pbData, pb, cb);
550 /* The updates of a (bogus) definite-length encoded message */
551 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
552 0x07,0x01,0xa0,0x02,0x04,0x00 };
553 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
554 static CRYPT_DATA_BLOB b1[] = {
559 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
560 /* The updates of a definite-length encoded message */
561 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
562 0x07,0x01,0xa0,0x06,0x04,0x04 };
563 static CRYPT_DATA_BLOB b2[] = {
567 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
568 /* The updates of an indefinite-length encoded message */
569 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
570 0x07,0x01,0xa0,0x80,0x24,0x80 };
571 static BYTE u5[] = { 0x04,0x04 };
572 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
573 static CRYPT_DATA_BLOB b3[] = {
581 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
583 static void check_updates(LPCSTR header, const struct update_accum *expected,
584 const struct update_accum *got)
588 ok(expected->cUpdates == got->cUpdates,
589 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
591 if (expected->cUpdates == got->cUpdates)
592 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
594 ok(expected->updates[i].cbData == got->updates[i].cbData,
595 "%s, update %d: expected %d bytes, got %d\n", header, i,
596 expected->updates[i].cbData, got->updates[i].cbData);
597 if (expected->updates[i].cbData && expected->updates[i].cbData ==
598 got->updates[i].cbData)
599 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
600 got->updates[i].cbData), "%s, update %d: unexpected value\n",
605 /* Frees the updates stored in accum */
606 static void free_updates(struct update_accum *accum)
610 for (i = 0; i < accum->cUpdates; i++)
611 CryptMemFree(accum->updates[i].pbData);
612 CryptMemFree(accum->updates);
613 accum->updates = NULL;
617 static void test_data_msg_encoding(void)
621 static char oid[] = "1.2.3";
622 struct update_accum accum = { 0, NULL };
623 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
625 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
627 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
628 dataEmptyBareContent, sizeof(dataEmptyBareContent));
629 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
630 sizeof(dataEmptyContent));
631 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
632 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
633 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
634 dataBareContent, sizeof(dataBareContent));
635 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
636 sizeof(dataContent));
638 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
639 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
640 CMSG_DATA, NULL, NULL, NULL);
641 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
642 dataEmptyBareContent, sizeof(dataEmptyBareContent));
643 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
644 sizeof(dataEmptyContent));
645 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
646 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
647 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
648 dataBareContent, sizeof(dataBareContent));
649 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
650 sizeof(dataContent));
652 /* The inner OID is apparently ignored */
653 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
655 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
656 dataEmptyBareContent, sizeof(dataEmptyBareContent));
657 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
658 dataEmptyContent, sizeof(dataEmptyContent));
659 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
660 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
661 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
662 dataBareContent, sizeof(dataBareContent));
663 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
664 sizeof(dataContent));
666 /* A streaming message is DER encoded if the length is not 0xffffffff, but
667 * curiously, updates aren't validated to make sure they don't exceed the
668 * stated length. (The resulting output will of course fail to decode.)
670 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
672 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
673 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
675 check_updates("bogus data message with definite length", &a1, &accum);
676 free_updates(&accum);
677 /* A valid definite-length encoding: */
678 streamInfo.cbContent = sizeof(msgData);
679 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
681 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
683 check_updates("data message with definite length", &a2, &accum);
684 free_updates(&accum);
685 /* An indefinite-length encoding: */
686 streamInfo.cbContent = 0xffffffff;
687 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
689 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
690 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
692 check_updates("data message with indefinite length", &a3, &accum);
693 free_updates(&accum);
696 static void test_data_msg(void)
698 test_data_msg_open();
699 test_data_msg_update();
700 test_data_msg_get_param();
701 test_data_msg_encoding();
704 static void test_hash_msg_open(void)
707 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
708 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
710 SetLastError(0xdeadbeef);
711 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
713 ok(!msg && GetLastError() == E_INVALIDARG,
714 "Expected E_INVALIDARG, got %x\n", GetLastError());
715 hashInfo.cbSize = sizeof(hashInfo);
716 SetLastError(0xdeadbeef);
717 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
719 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
720 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
721 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
722 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
724 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
726 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
727 CMSG_HASHED, &hashInfo, NULL, NULL);
728 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
730 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
731 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
732 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
736 static void test_hash_msg_update(void)
740 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
741 { oid_rsa_md5, { 0, NULL } }, NULL };
742 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
744 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
745 CMSG_HASHED, &hashInfo, NULL, NULL);
746 /* Detached hashed messages opened in non-streaming mode allow non-final
749 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
750 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
751 /* including non-final updates with no data.. */
752 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
753 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
754 /* and final updates with no data. */
755 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
756 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
757 /* But no updates are allowed after the final update. */
758 SetLastError(0xdeadbeef);
759 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
760 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
761 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
762 SetLastError(0xdeadbeef);
763 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
764 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
765 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
767 /* Non-detached messages, in contrast, don't allow non-final updates in
768 * non-streaming mode.
770 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
772 SetLastError(0xdeadbeef);
773 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
774 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
775 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
776 /* Final updates (including empty ones) are allowed. */
777 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
778 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
780 /* And, of course, streaming mode allows non-final updates */
781 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
783 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
784 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
786 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
787 * to be a bug, it isn't actually used - see encoding tests.)
789 streamInfo.pfnStreamOutput = NULL;
790 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
792 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
793 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
797 static const BYTE emptyHashParam[] = {
798 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
801 static void test_hash_msg_get_param(void)
805 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
806 { oid_rsa_md5, { 0, NULL } }, NULL };
808 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
811 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
813 /* Content and bare content are always gettable for non-streamed messages */
815 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
816 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
817 "CryptMsgGetParam failed: %08x\n", GetLastError());
819 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
820 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
821 "CryptMsgGetParam failed: %08x\n", GetLastError());
822 /* For an encoded hash message, the hash data aren't available */
823 SetLastError(0xdeadbeef);
824 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
825 ok(!ret && (GetLastError() == CRYPT_E_INVALID_MSG_TYPE ||
826 GetLastError() == OSS_LIMITED /* Win9x */),
827 "Expected CRYPT_E_INVALID_MSG_TYPE or OSS_LIMITED, got %08x\n",
829 /* The hash is also available. */
831 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
832 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
833 ok(size == sizeof(buf), "Unexpected size %d\n", size);
834 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
835 if (size == sizeof(buf))
836 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
837 /* By getting the hash, further updates are not allowed */
838 SetLastError(0xdeadbeef);
839 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
841 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
842 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
843 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
844 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
845 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
847 /* Even after a final update, the hash data aren't available */
848 SetLastError(0xdeadbeef);
849 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
850 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
851 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
852 /* The version is also available, and should be zero for this message. */
854 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
855 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
856 "CryptMsgGetParam failed: %08x\n", GetLastError());
857 size = sizeof(value);
858 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
859 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
860 "CryptMsgGetParam failed: %08x\n", GetLastError());
862 ok(value == 0, "Expected version 0, got %d\n", value);
863 /* As usual, the type isn't available. */
864 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
865 ok(!ret, "Expected failure\n");
868 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
870 /* Streamed messages don't allow you to get the content or bare content. */
871 SetLastError(0xdeadbeef);
872 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
873 ok(!ret && (GetLastError() == E_INVALIDARG ||
874 GetLastError() == OSS_LIMITED /* Win9x */),
875 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
876 SetLastError(0xdeadbeef);
877 ret = CryptMsgGetParam(msg, CMSG_BARE_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 /* The hash is still available. */
883 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
884 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
885 ok(size == sizeof(buf), "Unexpected size %d\n", size);
886 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
887 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
888 if (size == sizeof(buf))
889 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
890 /* After updating the hash, further updates aren't allowed on streamed
893 SetLastError(0xdeadbeef);
894 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
896 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
897 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
898 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
899 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
900 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
905 static const BYTE hashEmptyBareContent[] = {
906 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
907 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
908 static const BYTE hashEmptyContent[] = {
909 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
910 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
911 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
912 static const BYTE hashBareContent[] = {
913 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
914 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
915 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
916 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
917 static const BYTE hashContent[] = {
918 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
919 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
920 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
921 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
922 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
924 static const BYTE detachedHashNonFinalBareContent[] = {
925 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
926 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
927 0x07,0x01,0x04,0x00 };
928 static const BYTE detachedHashNonFinalContent[] = {
929 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
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 detachedHashBareContent[] = {
934 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
935 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
936 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
937 0x9d,0x2a,0x8f,0x26,0x2f };
938 static const BYTE detachedHashContent[] = {
939 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
940 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
941 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
942 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
943 0x9d,0x2a,0x8f,0x26,0x2f };
945 static void test_hash_msg_encoding(void)
948 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
950 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
951 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
953 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
954 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
956 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
957 hashEmptyBareContent, sizeof(hashEmptyBareContent));
958 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
959 hashEmptyContent, sizeof(hashEmptyContent));
960 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
961 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
962 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
963 hashBareContent, sizeof(hashBareContent));
964 check_param("hash content", msg, CMSG_CONTENT_PARAM,
965 hashContent, sizeof(hashContent));
967 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
968 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
969 CMSG_HASHED, &hashInfo, NULL, NULL);
970 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
971 hashEmptyBareContent, sizeof(hashEmptyBareContent));
972 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
973 hashEmptyContent, sizeof(hashEmptyContent));
974 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
975 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
976 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
977 hashBareContent, sizeof(hashBareContent));
978 check_param("hash content", msg, CMSG_CONTENT_PARAM,
979 hashContent, sizeof(hashContent));
981 /* Same test, but with CMSG_DETACHED_FLAG set */
982 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
983 CMSG_HASHED, &hashInfo, NULL, NULL);
984 check_param("detached hash empty bare content", msg,
985 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
986 sizeof(hashEmptyBareContent));
987 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
988 hashEmptyContent, sizeof(hashEmptyContent));
989 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
990 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
991 check_param("detached hash not final bare content", msg,
992 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
993 sizeof(detachedHashNonFinalBareContent));
994 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
995 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
996 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
997 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
998 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
999 detachedHashBareContent, sizeof(detachedHashBareContent));
1000 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1001 detachedHashContent, sizeof(detachedHashContent));
1002 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1003 detachedHashBareContent, sizeof(detachedHashBareContent));
1004 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1005 detachedHashContent, sizeof(detachedHashContent));
1007 /* In what appears to be a bug, streamed updates to hash messages don't
1008 * call the output function.
1010 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
1012 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1013 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1014 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1015 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1017 check_updates("empty hash message", &empty_accum, &accum);
1018 free_updates(&accum);
1020 streamInfo.cbContent = sizeof(msgData);
1021 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
1023 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1024 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1026 check_updates("hash message", &empty_accum, &accum);
1027 free_updates(&accum);
1029 streamInfo.cbContent = sizeof(msgData);
1030 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
1031 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
1032 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1033 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1035 check_updates("detached hash message", &empty_accum, &accum);
1036 free_updates(&accum);
1039 static void test_hash_msg(void)
1041 test_hash_msg_open();
1042 test_hash_msg_update();
1043 test_hash_msg_get_param();
1044 test_hash_msg_encoding();
1047 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1049 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1051 static BYTE serialNum[] = { 1 };
1052 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1053 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1055 static void test_signed_msg_open(void)
1059 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1060 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1061 CERT_INFO certInfo = { 0 };
1063 SetLastError(0xdeadbeef);
1064 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1066 ok(!msg && GetLastError() == E_INVALIDARG,
1067 "Expected E_INVALIDARG, got %x\n", GetLastError());
1068 signInfo.cbSize = sizeof(signInfo);
1069 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1071 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1074 signInfo.cSigners = 1;
1075 signInfo.rgSigners = &signer;
1076 /* With signer.pCertInfo unset, attempting to open this message this
1079 signer.pCertInfo = &certInfo;
1080 /* The cert info must contain a serial number and an issuer. */
1081 SetLastError(0xdeadbeef);
1082 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1084 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1085 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1086 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1087 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1090 certInfo.SerialNumber.cbData = sizeof(serialNum);
1091 certInfo.SerialNumber.pbData = serialNum;
1092 SetLastError(0xdeadbeef);
1093 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1095 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1096 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1097 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1098 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1101 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1102 certInfo.Issuer.pbData = encodedCommonName;
1103 SetLastError(0xdeadbeef);
1104 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1106 ok(!msg && (GetLastError() == E_INVALIDARG ||
1107 GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1108 "Expected E_INVALIDARG or CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1110 /* The signer's hCryptProv must be set to something. Whether it's usable
1111 * or not will be checked after the hash algorithm is checked (see next
1114 signer.hCryptProv = 1;
1115 SetLastError(0xdeadbeef);
1116 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1118 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1119 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1120 /* The signer's hash algorithm must also be set. */
1121 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1122 SetLastError(0xdeadbeef);
1123 /* Crashes in advapi32 in wine, don't do it */
1125 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1126 &signInfo, NULL, NULL);
1127 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1128 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1130 /* The signer's hCryptProv must also be valid. */
1131 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1132 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1133 if (!ret && GetLastError() == NTE_EXISTS) {
1134 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1137 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1140 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1142 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1146 /* pCertInfo must still be set, but can be empty if the SignerId's issuer
1147 * and serial number are set.
1149 certInfo.Issuer.cbData = 0;
1150 certInfo.SerialNumber.cbData = 0;
1151 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1152 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1153 sizeof(encodedCommonName);
1154 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1155 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1157 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1158 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1160 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1163 CryptReleaseContext(signer.hCryptProv, 0);
1164 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1165 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1168 static const BYTE privKey[] = {
1169 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1170 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1171 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1172 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1173 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1174 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1175 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1176 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1177 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1178 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1179 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1180 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1181 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1182 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1183 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1184 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1185 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1186 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1187 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1188 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1189 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1190 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1191 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1192 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1193 static BYTE pubKey[] = {
1194 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1195 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1196 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1197 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1198 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1200 static void test_signed_msg_update(void)
1204 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1205 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1206 CERT_INFO certInfo = { 0 };
1209 certInfo.SerialNumber.cbData = sizeof(serialNum);
1210 certInfo.SerialNumber.pbData = serialNum;
1211 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1212 certInfo.Issuer.pbData = encodedCommonName;
1213 signer.pCertInfo = &certInfo;
1214 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1215 signInfo.cSigners = 1;
1216 signInfo.rgSigners = &signer;
1218 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1219 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1220 if (!ret && GetLastError() == NTE_EXISTS) {
1221 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1224 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1227 skip("No context for tests\n");
1231 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1232 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1233 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1234 /* Detached CMSG_SIGNED allows non-final updates. */
1235 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1236 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1237 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1238 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1239 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1240 /* The final update requires a private key in the hCryptProv, in order to
1241 * generate the signature.
1243 SetLastError(0xdeadbeef);
1244 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1246 (GetLastError() == NTE_BAD_KEYSET ||
1247 GetLastError() == NTE_NO_KEY ||
1248 broken(GetLastError() == ERROR_SUCCESS)), /* Some Win9x */
1249 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1250 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1252 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1253 /* The final update should be able to succeed now that a key exists, but
1254 * the previous (invalid) final update prevents it.
1256 SetLastError(0xdeadbeef);
1257 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1258 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1259 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1262 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1263 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1264 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1265 /* Detached CMSG_SIGNED allows non-final updates. */
1266 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1267 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1268 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1269 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1270 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1271 /* Now that the private key exists, the final update can succeed (even
1274 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1275 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1276 /* But no updates are allowed after the final update. */
1277 SetLastError(0xdeadbeef);
1278 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1279 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1280 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1281 SetLastError(0xdeadbeef);
1282 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1283 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1284 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1287 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1289 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1290 /* Non-detached messages don't allow non-final updates.. */
1291 SetLastError(0xdeadbeef);
1292 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1293 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1294 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1295 /* but they do allow final ones. */
1296 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1297 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1299 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1301 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1302 /* They also allow final updates with no data. */
1303 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1304 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1307 CryptDestroyKey(key);
1308 CryptReleaseContext(signer.hCryptProv, 0);
1309 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1310 CRYPT_DELETEKEYSET);
1313 static const BYTE signedEmptyBareContent[] = {
1314 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1315 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1316 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1317 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1318 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1319 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1320 static const BYTE signedEmptyContent[] = {
1321 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1322 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1323 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1324 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1325 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1326 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1327 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1328 static const BYTE detachedSignedBareContent[] = {
1329 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1330 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1331 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1332 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1333 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1334 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1335 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1336 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1337 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1338 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1339 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1340 static const BYTE detachedSignedContent[] = {
1341 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1342 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1343 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1344 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1345 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1346 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1347 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1348 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1349 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1350 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1351 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1352 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1353 static const BYTE signedBareContent[] = {
1354 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1355 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1356 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1357 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1358 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1359 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1360 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1361 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1362 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1363 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1364 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1365 static const BYTE signedContent[] = {
1366 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1367 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1368 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1369 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1370 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1371 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1372 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1373 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1374 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1375 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1376 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1377 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1379 static const BYTE signedHash[] = {
1380 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1382 static const BYTE signedKeyIdEmptyContent[] = {
1383 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
1384 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1385 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
1386 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1387 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1388 static const BYTE signedEncodedSigner[] = {
1389 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1390 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1391 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1392 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1393 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1394 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1395 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1396 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1397 static const BYTE signedWithAuthAttrsBareContent[] = {
1398 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1399 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1400 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1401 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1402 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1403 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1404 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1405 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1406 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1407 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1408 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1409 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1410 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1411 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1412 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1413 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1414 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1415 0xff,0xc6,0x33,0x63,0x34 };
1416 static BYTE cert[] = {
1417 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1418 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1419 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1420 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1421 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1422 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1423 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1424 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1425 0xff,0x02,0x01,0x01 };
1426 static BYTE v1CertWithPubKey[] = {
1427 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1428 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1429 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1430 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1431 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1432 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1433 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1434 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1435 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1436 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1438 static const BYTE signedWithCertEmptyBareContent[] = {
1439 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1440 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1441 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1442 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1443 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1444 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1445 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1446 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1447 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1448 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1449 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1450 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1451 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1452 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1453 static const BYTE signedWithCertBareContent[] = {
1454 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1455 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1456 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1457 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1458 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1459 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1460 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1461 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1462 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1463 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1464 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1465 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1466 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1467 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1468 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1469 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1470 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1471 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1472 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1473 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1474 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1475 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1476 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1477 0x30,0x30,0x30,0x30,0x5a };
1478 static const BYTE signedWithCrlEmptyBareContent[] = {
1479 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1480 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1481 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1482 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1483 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1484 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1485 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1486 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1487 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1488 static const BYTE signedWithCrlBareContent[] = {
1489 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1490 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1491 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1492 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1493 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1494 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1495 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1496 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1497 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1498 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1499 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1500 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1501 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1502 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1504 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1505 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1506 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1507 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1508 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1509 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1510 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1511 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1512 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1513 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1514 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1515 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1516 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1517 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1518 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1519 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1520 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1521 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1523 static const BYTE signedWithCertAndCrlBareContent[] = {
1524 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1525 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1526 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1527 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1528 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1529 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1530 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1531 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1532 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1533 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1534 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1535 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1536 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1537 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1538 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1539 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1540 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1541 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1542 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1543 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1544 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1545 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1546 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1547 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1548 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1549 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1550 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1551 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1552 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1553 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1554 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1555 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1556 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1557 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1558 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1559 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1560 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1561 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1562 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1563 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1564 static BYTE v1CertWithValidPubKey[] = {
1565 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,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,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1568 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1569 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1570 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1571 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1572 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1573 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1574 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1575 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1576 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1577 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1578 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1579 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1580 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1581 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1582 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1583 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1584 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1585 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1586 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1587 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1588 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1589 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1590 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1591 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1592 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1593 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1594 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1595 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1596 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1597 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1598 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1599 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1600 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1602 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1603 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1604 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1605 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1606 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1607 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1608 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1609 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1610 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1611 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1612 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1613 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1614 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1615 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1616 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1617 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1618 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1619 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1620 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1621 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1622 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1623 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1624 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1625 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1626 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1627 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1628 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1629 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1631 static void test_signed_msg_encoding(void)
1634 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1635 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1636 CERT_INFO certInfo = { 0 };
1637 CERT_BLOB encodedCert = { sizeof(cert), cert };
1638 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1639 char oid_common_name[] = szOID_COMMON_NAME;
1640 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1641 encodedCommonName };
1642 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1647 certInfo.SerialNumber.cbData = sizeof(serialNum);
1648 certInfo.SerialNumber.pbData = serialNum;
1649 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1650 certInfo.Issuer.pbData = encodedCommonName;
1651 signer.pCertInfo = &certInfo;
1652 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1653 signInfo.cSigners = 1;
1654 signInfo.rgSigners = &signer;
1656 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1657 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1658 if (!ret && GetLastError() == NTE_EXISTS) {
1659 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1662 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1665 skip("No context for tests\n");
1669 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1671 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1673 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1674 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1675 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1677 check_param("detached signed empty bare content", msg,
1678 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1679 sizeof(signedEmptyBareContent));
1680 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1681 signedEmptyContent, sizeof(signedEmptyContent));
1682 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1683 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1684 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1685 signedHash, sizeof(signedHash));
1686 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1687 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1688 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1689 detachedSignedContent, sizeof(detachedSignedContent));
1690 SetLastError(0xdeadbeef);
1691 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1692 ok(!ret && (GetLastError() == CRYPT_E_INVALID_INDEX ||
1693 broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */)),
1694 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1695 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1696 signedEncodedSigner, sizeof(signedEncodedSigner));
1700 certInfo.SerialNumber.cbData = 0;
1701 certInfo.Issuer.cbData = 0;
1702 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1703 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1704 U(signer.SignerId).KeyId.pbData = serialNum;
1705 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1707 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1708 check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM,
1709 signedKeyIdEmptyContent, sizeof(signedKeyIdEmptyContent));
1712 certInfo.SerialNumber.cbData = sizeof(serialNum);
1713 certInfo.SerialNumber.pbData = serialNum;
1714 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1715 certInfo.Issuer.pbData = encodedCommonName;
1716 signer.SignerId.dwIdChoice = 0;
1717 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1719 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1721 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1722 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1723 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1724 signedEmptyContent, sizeof(signedEmptyContent));
1725 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1726 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1727 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1728 signedBareContent, sizeof(signedBareContent));
1729 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1730 signedContent, sizeof(signedContent));
1734 signer.cAuthAttr = 1;
1735 signer.rgAuthAttr = &attr;
1736 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1738 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1740 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1741 check_param("signed with auth attrs bare content", msg,
1742 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1743 sizeof(signedWithAuthAttrsBareContent));
1747 signer.cAuthAttr = 0;
1748 signInfo.rgCertEncoded = &encodedCert;
1749 signInfo.cCertEncoded = 1;
1750 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1752 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1754 check_param("signed with cert empty bare content", msg,
1755 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1756 sizeof(signedWithCertEmptyBareContent));
1757 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1758 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1759 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1760 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1764 signInfo.cCertEncoded = 0;
1765 signInfo.rgCrlEncoded = &encodedCrl;
1766 signInfo.cCrlEncoded = 1;
1767 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1769 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1771 check_param("signed with crl empty bare content", msg,
1772 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1773 sizeof(signedWithCrlEmptyBareContent));
1774 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1775 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1776 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1777 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1781 signInfo.cCertEncoded = 1;
1782 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1784 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1786 check_param("signed with cert and crl empty bare content", msg,
1787 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1788 sizeof(signedWithCertAndCrlEmptyBareContent));
1789 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1790 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1791 check_param("signed with cert and crl bare content", msg,
1792 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1793 sizeof(signedWithCertAndCrlBareContent));
1797 /* Test with a cert with a (bogus) public key */
1798 signInfo.cCrlEncoded = 0;
1799 encodedCert.cbData = sizeof(v1CertWithPubKey);
1800 encodedCert.pbData = v1CertWithPubKey;
1801 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1803 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1804 check_param("signedWithCertWithPubKeyBareContent", msg,
1805 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1806 sizeof(signedWithCertWithPubKeyBareContent));
1809 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1810 encodedCert.pbData = v1CertWithValidPubKey;
1811 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1813 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1814 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1815 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1816 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1817 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1818 check_param("signedWithCertWithValidPubKeyContent", msg,
1819 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1820 sizeof(signedWithCertWithValidPubKeyContent));
1823 CryptDestroyKey(key);
1824 CryptReleaseContext(signer.hCryptProv, 0);
1825 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1826 CRYPT_DELETEKEYSET);
1829 static void test_signed_msg_get_param(void)
1833 DWORD size, value = 0;
1834 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1835 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1836 CERT_INFO certInfo = { 0 };
1838 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1840 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1842 /* Content and bare content are always gettable */
1844 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1845 ok(ret || broken(!ret /* Win9x */), "CryptMsgGetParam failed: %08x\n",
1849 skip("message parameters are broken, skipping tests\n");
1853 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1854 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1855 /* For "signed" messages, so is the version. */
1857 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1858 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1859 size = sizeof(value);
1860 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1861 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1862 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1863 /* But for this message, with no signers, the hash and signer aren't
1867 SetLastError(0xdeadbeef);
1868 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1869 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1870 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1871 SetLastError(0xdeadbeef);
1872 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1873 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1874 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1875 /* As usual, the type isn't available. */
1876 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1877 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1878 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1882 certInfo.SerialNumber.cbData = sizeof(serialNum);
1883 certInfo.SerialNumber.pbData = serialNum;
1884 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1885 certInfo.Issuer.pbData = encodedCommonName;
1886 signer.pCertInfo = &certInfo;
1887 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1888 signInfo.cSigners = 1;
1889 signInfo.rgSigners = &signer;
1891 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1892 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1893 if (!ret && GetLastError() == NTE_EXISTS) {
1894 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1897 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1900 skip("No context for tests\n");
1904 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1906 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1908 /* This message, with one signer, has the hash and signer for index 0
1909 * available, but not for other indexes.
1912 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1913 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1914 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1915 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1917 SetLastError(0xdeadbeef);
1918 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1919 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1920 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1921 SetLastError(0xdeadbeef);
1922 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1923 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1924 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1925 /* As usual, the type isn't available. */
1926 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1927 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1928 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1932 /* Opening the message using the CMS fields.. */
1933 certInfo.SerialNumber.cbData = 0;
1934 certInfo.Issuer.cbData = 0;
1935 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1936 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1937 sizeof(encodedCommonName);
1938 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1939 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1941 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1942 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1943 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1944 if (!ret && GetLastError() == NTE_EXISTS)
1945 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1947 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1948 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1949 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1950 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1951 /* still results in the version being 1 when the issuer and serial number
1952 * are used and no additional CMS fields are used.
1954 size = sizeof(value);
1955 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1956 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE),
1957 "CryptMsgGetParam failed: %08x\n", GetLastError());
1959 ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value);
1960 /* Apparently the encoded signer can be retrieved.. */
1961 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1962 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1963 /* but the signer info, CMS signer info, and cert ID can't be. */
1964 SetLastError(0xdeadbeef);
1965 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1966 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1967 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1968 SetLastError(0xdeadbeef);
1969 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1970 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1971 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1972 SetLastError(0xdeadbeef);
1973 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1974 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1975 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1978 /* Using the KeyId field of the SignerId results in the version becoming
1981 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1982 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1983 U(signer.SignerId).KeyId.pbData = serialNum;
1984 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1985 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1986 if (!ret && GetLastError() == NTE_EXISTS)
1987 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1989 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1990 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1991 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1992 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1993 size = sizeof(value);
1994 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1995 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1997 ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value);
1998 /* Even for a CMS message, the signer can be retrieved.. */
1999 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
2000 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2001 /* but the signer info, CMS signer info, and cert ID can't be. */
2002 SetLastError(0xdeadbeef);
2003 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2004 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2005 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2006 SetLastError(0xdeadbeef);
2007 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2008 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2009 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2010 SetLastError(0xdeadbeef);
2011 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
2012 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2013 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2016 CryptReleaseContext(signer.hCryptProv, 0);
2017 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
2018 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2021 static void test_signed_msg(void)
2023 test_signed_msg_open();
2024 test_signed_msg_update();
2025 test_signed_msg_encoding();
2026 test_signed_msg_get_param();
2029 static CRYPT_DATA_BLOB b4 = { 0, NULL };
2030 static const struct update_accum a4 = { 1, &b4 };
2032 static const BYTE bogusOIDContent[] = {
2033 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2035 static const BYTE bogusHashContent[] = {
2036 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2037 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2038 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2039 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2040 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2042 static void test_decode_msg_update(void)
2046 CMSG_STREAM_INFO streamInfo = { 0 };
2048 struct update_accum accum = { 0, NULL };
2050 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2051 /* Update with a full message in a final update */
2052 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2053 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2054 /* Can't update after a final update */
2055 SetLastError(0xdeadbeef);
2056 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2057 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2058 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2061 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2062 /* Can't send a non-final update without streaming */
2063 SetLastError(0xdeadbeef);
2064 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2066 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2067 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2068 /* A subsequent final update succeeds */
2069 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2070 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2075 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2076 /* Updating a message that has a NULL stream callback fails */
2077 SetLastError(0xdeadbeef);
2078 /* Crashes on some Win9x */
2079 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2082 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2083 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2084 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2086 /* Changing the callback pointer after the fact yields the same error (so
2087 * the message must copy the stream info, not just store a pointer to it)
2089 streamInfo.pfnStreamOutput = nop_stream_output;
2090 SetLastError(0xdeadbeef);
2091 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2094 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2095 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2096 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2101 /* Empty non-final updates are allowed when streaming.. */
2102 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2103 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2104 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2105 /* but final updates aren't when not enough data has been received. */
2106 SetLastError(0xdeadbeef);
2107 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2109 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2110 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2113 /* Updating the message byte by byte is legal */
2114 streamInfo.pfnStreamOutput = accumulating_stream_output;
2115 streamInfo.pvArg = &accum;
2116 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2117 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2118 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2119 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2120 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2121 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2124 check_updates("byte-by-byte empty content", &a4, &accum);
2125 free_updates(&accum);
2127 /* Decoding bogus content fails in non-streaming mode.. */
2128 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2129 SetLastError(0xdeadbeef);
2130 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2131 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2132 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2133 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2136 /* and as the final update in streaming mode.. */
2137 streamInfo.pfnStreamOutput = nop_stream_output;
2138 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2139 SetLastError(0xdeadbeef);
2140 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2141 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2142 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2143 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2146 /* and even as a non-final update in streaming mode. */
2147 streamInfo.pfnStreamOutput = nop_stream_output;
2148 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2149 SetLastError(0xdeadbeef);
2150 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2152 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2153 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2154 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2158 /* An empty message can be opened with undetermined type.. */
2159 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2160 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2162 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2164 /* but decoding it as an explicitly typed message fails. */
2165 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2167 SetLastError(0xdeadbeef);
2168 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2170 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2171 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2172 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2175 /* On the other hand, decoding the bare content of an empty message fails
2176 * with unspecified type..
2178 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2179 SetLastError(0xdeadbeef);
2180 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2181 sizeof(dataEmptyBareContent), TRUE);
2182 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2183 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2184 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2187 /* but succeeds with explicit type. */
2188 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2190 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2191 sizeof(dataEmptyBareContent), TRUE);
2192 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2195 /* Decoding valid content with an unsupported OID fails */
2196 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2197 SetLastError(0xdeadbeef);
2198 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2199 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2200 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2203 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2204 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2205 SetLastError(0xdeadbeef);
2206 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2207 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2208 "CryptMsgUpdate failed: %08x\n", GetLastError());
2210 /* while with specified type it fails. */
2211 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2213 SetLastError(0xdeadbeef);
2214 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2215 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2216 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2217 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2218 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2221 /* On the other hand, decoding the bare content of an empty hash message
2222 * fails with unspecified type..
2224 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2225 SetLastError(0xdeadbeef);
2226 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2227 sizeof(hashEmptyBareContent), TRUE);
2228 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2229 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2230 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2231 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2234 /* but succeeds with explicit type. */
2235 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2237 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2238 sizeof(hashEmptyBareContent), TRUE);
2239 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2240 "CryptMsgUpdate failed: %x\n", GetLastError());
2243 /* And again, opening a (non-empty) hash message with unspecified type
2246 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2247 SetLastError(0xdeadbeef);
2248 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2249 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2251 /* while with specified type it fails.. */
2252 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2254 SetLastError(0xdeadbeef);
2255 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2256 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2257 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2258 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2259 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2262 /* and decoding the bare content of a non-empty hash message fails with
2263 * unspecified type..
2265 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2266 SetLastError(0xdeadbeef);
2267 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2268 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2269 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2270 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2271 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2274 /* but succeeds with explicit type. */
2275 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2277 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2278 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2281 /* Opening a (non-empty) hash message with unspecified type and a bogus
2282 * hash value succeeds..
2284 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2285 SetLastError(0xdeadbeef);
2286 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2287 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2290 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2291 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2292 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2294 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2295 SetLastError(0xdeadbeef);
2296 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2297 sizeof(signedWithCertAndCrlBareContent), TRUE);
2298 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2299 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2300 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2303 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2305 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2306 sizeof(signedWithCertAndCrlBareContent), TRUE);
2307 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2310 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2312 /* The first update succeeds.. */
2313 ret = CryptMsgUpdate(msg, detachedSignedContent,
2314 sizeof(detachedSignedContent), TRUE);
2315 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2316 /* as does a second (probably to update the detached portion).. */
2317 ret = CryptMsgUpdate(msg, detachedSignedContent,
2318 sizeof(detachedSignedContent), TRUE);
2319 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2320 /* while a third fails. */
2321 ret = CryptMsgUpdate(msg, detachedSignedContent,
2322 sizeof(detachedSignedContent), TRUE);
2323 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2324 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2327 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2328 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2329 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2330 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2331 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2332 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2333 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2334 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2335 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2337 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2338 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2339 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2343 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2344 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2346 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2347 const CMSG_SIGNER_INFO *expected)
2349 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2350 expected->dwVersion, got->dwVersion);
2351 ok(got->Issuer.cbData == expected->Issuer.cbData,
2352 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2353 got->Issuer.cbData);
2354 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2355 "Unexpected issuer\n");
2356 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2357 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2358 got->SerialNumber.cbData);
2359 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2360 got->SerialNumber.cbData), "Unexpected serial number\n");
2361 /* FIXME: check more things */
2364 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2365 const CMSG_CMS_SIGNER_INFO *expected)
2367 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2368 expected->dwVersion, got->dwVersion);
2369 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2370 "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2371 got->SignerId.dwIdChoice);
2372 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2374 if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2376 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2377 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2378 "Expected issuer size %d, got %d\n",
2379 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2380 U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2381 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2382 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2383 U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2384 "Unexpected issuer\n");
2385 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2386 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2387 "Expected serial number size %d, got %d\n",
2388 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2389 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2390 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2391 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2392 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2393 "Unexpected serial number\n");
2397 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2398 "expected key id size %d, got %d\n",
2399 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2400 ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2401 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2402 "unexpected key id\n");
2405 /* FIXME: check more things */
2408 static const BYTE signedWithCertAndCrlComputedHash[] = {
2409 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2411 static BYTE keyIdIssuer[] = {
2412 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2413 0x0a,0x07,0x01,0x04,0x01,0x01 };
2415 static void test_decode_msg_get_param(void)
2419 DWORD size = 0, value;
2422 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2423 SetLastError(0xdeadbeef);
2424 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2425 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2426 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2427 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2428 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2432 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2433 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2436 /* Crashes on some Win9x */
2437 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2438 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2439 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2440 emptyHashParam, sizeof(emptyHashParam));
2443 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2444 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2445 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2447 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2449 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2450 hashParam, sizeof(hashParam));
2451 /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2452 * even though there's only one hash.
2454 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2455 ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2456 "CryptMsgGetParam failed: %08x\n", GetLastError());
2458 buf = CryptMemAlloc(size);
2463 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2464 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2465 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2468 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2469 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2470 value = CMSG_HASHED_DATA_V0;
2471 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2475 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2476 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2477 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2478 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2480 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2481 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2482 size = sizeof(value);
2484 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2485 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2486 ok(value == 1, "Expected 1 signer, got %d\n", value);
2488 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2489 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2490 "CryptMsgGetParam failed: %08x\n", GetLastError());
2492 buf = CryptMemAlloc(size);
2497 CMSG_SIGNER_INFO signer = { 0 };
2499 signer.dwVersion = 1;
2500 signer.Issuer.cbData = sizeof(encodedCommonName);
2501 signer.Issuer.pbData = encodedCommonName;
2502 signer.SerialNumber.cbData = sizeof(serialNum);
2503 signer.SerialNumber.pbData = serialNum;
2504 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2505 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2506 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2509 /* Getting the CMS signer info of a PKCS7 message is possible. */
2511 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2512 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2513 "CryptMsgGetParam failed: %08x\n", GetLastError());
2515 buf = CryptMemAlloc(size);
2520 CMSG_CMS_SIGNER_INFO signer = { 0 };
2522 signer.dwVersion = 1;
2523 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2524 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2525 sizeof(encodedCommonName);
2526 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2527 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2529 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2530 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2531 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2532 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2535 /* index is ignored when getting signer count */
2536 size = sizeof(value);
2537 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2538 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2539 ok(value == 1, "Expected 1 signer, got %d\n", value);
2540 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2541 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2542 ok(value == 0, "Expected 0 certs, got %d\n", value);
2543 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2544 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2545 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2547 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2549 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2550 sizeof(signedWithCertAndCrlBareContent), TRUE);
2551 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2552 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2553 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2554 ok(value == 1, "Expected 1 cert, got %d\n", value);
2555 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2556 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2557 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2558 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2559 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2560 check_param("signed with cert and CRL computed hash", msg,
2561 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2562 sizeof(signedWithCertAndCrlComputedHash));
2565 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2566 ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
2567 sizeof(signedKeyIdEmptyContent), TRUE);
2568 if (!ret && GetLastError() == OSS_DATA_ERROR)
2570 /* Subsequent tests crashes on some Win9x, so bail out */
2574 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2575 size = sizeof(value);
2576 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2577 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2578 ok(value == 1, "Expected 1 signer, got %d\n", value);
2579 /* Getting the regular (non-CMS) signer info from a CMS message is also
2583 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2584 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2586 buf = CryptMemAlloc(size);
2591 CMSG_SIGNER_INFO signer;
2594 /* and here's the little oddity: for a CMS message using the key id
2595 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
2596 * a signer with a zero (not empty) serial number, and whose issuer is
2597 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
2598 * and value of the key id.
2600 signer.dwVersion = CMSG_SIGNED_DATA_V3;
2601 signer.Issuer.cbData = sizeof(keyIdIssuer);
2602 signer.Issuer.pbData = keyIdIssuer;
2603 signer.SerialNumber.cbData = 1;
2604 signer.SerialNumber.pbData = &zero;
2605 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2606 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2610 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2611 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2613 buf = CryptMemAlloc(size);
2618 CMSG_CMS_SIGNER_INFO signer = { 0 };
2620 signer.dwVersion = CMSG_SIGNED_DATA_V3;
2621 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2622 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
2623 U(signer.SignerId).KeyId.pbData = serialNum;
2624 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2625 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2626 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2632 static void test_decode_msg(void)
2634 test_decode_msg_update();
2635 test_decode_msg_get_param();
2638 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2639 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2640 static BYTE encodedPubKey[] = {
2641 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2642 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2644 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2645 static BYTE mod_encoded[] = {
2646 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2649 static void test_msg_control(void)
2651 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2655 CERT_INFO certInfo = { 0 };
2656 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2657 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2658 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2659 BOOL old_crypt32 = FALSE;
2661 /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
2662 if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
2664 win_skip("Some tests will crash on older crypt32 implementations\n");
2669 ret = CryptMsgControl(NULL, 0, 0, NULL);
2672 /* Data encode messages don't allow any sort of control.. */
2673 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2675 /* either with no prior update.. */
2676 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2678 SetLastError(0xdeadbeef);
2679 ret = CryptMsgControl(msg, 0, i, NULL);
2680 ok(!ret && GetLastError() == E_INVALIDARG,
2681 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2683 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2684 /* or after an update. */
2685 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2687 SetLastError(0xdeadbeef);
2688 ret = CryptMsgControl(msg, 0, i, NULL);
2689 ok(!ret && GetLastError() == E_INVALIDARG,
2690 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2694 /* Hash encode messages don't allow any sort of control.. */
2695 hashInfo.cbSize = sizeof(hashInfo);
2696 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2697 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2699 /* either with no prior update.. */
2700 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2702 SetLastError(0xdeadbeef);
2703 ret = CryptMsgControl(msg, 0, i, NULL);
2704 ok(!ret && GetLastError() == E_INVALIDARG,
2705 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2707 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2708 /* or after an update. */
2709 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2711 SetLastError(0xdeadbeef);
2712 ret = CryptMsgControl(msg, 0, i, NULL);
2713 ok(!ret && GetLastError() == E_INVALIDARG,
2714 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2718 /* Signed encode messages likewise don't allow any sort of control.. */
2719 signInfo.cbSize = sizeof(signInfo);
2720 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2722 /* either before an update.. */
2723 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2725 SetLastError(0xdeadbeef);
2726 ret = CryptMsgControl(msg, 0, i, NULL);
2727 ok(!ret && GetLastError() == E_INVALIDARG,
2728 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2730 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2731 /* or after an update. */
2732 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2734 SetLastError(0xdeadbeef);
2735 ret = CryptMsgControl(msg, 0, i, NULL);
2736 ok(!ret && GetLastError() == E_INVALIDARG,
2737 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2741 /* Decode messages behave a bit differently. */
2742 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2743 /* Bad control type */
2744 SetLastError(0xdeadbeef);
2745 ret = CryptMsgControl(msg, 0, 0, NULL);
2746 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2747 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2748 SetLastError(0xdeadbeef);
2749 ret = CryptMsgControl(msg, 1, 0, NULL);
2750 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2751 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2752 /* Can't verify the hash of an indeterminate-type message */
2753 SetLastError(0xdeadbeef);
2754 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2755 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2756 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2758 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2760 /* Can't decrypt an indeterminate-type message */
2761 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2762 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2763 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2768 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2770 /* Can't verify the hash of an empty message */
2771 SetLastError(0xdeadbeef);
2772 /* Crashes on some Win9x */
2773 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2775 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2776 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2778 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2780 /* Can't verify the signature of a hash message */
2781 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2782 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2783 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2784 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2786 /* Oddly enough, this fails, crashes on some Win9x */
2787 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2788 ok(!ret, "Expected failure\n");
2791 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2793 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2794 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2795 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2796 /* Can't decrypt an indeterminate-type message */
2797 SetLastError(0xdeadbeef);
2798 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2799 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2800 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2803 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2805 /* Can't verify the hash of a detached message before it's been updated. */
2806 SetLastError(0xdeadbeef);
2807 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2808 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2809 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2810 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
2812 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2813 /* Still can't verify the hash of a detached message with the content
2814 * of the detached hash given..
2816 SetLastError(0xdeadbeef);
2817 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2818 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
2819 "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
2820 /* and giving the content of the message after attempting to verify the
2823 SetLastError(0xdeadbeef);
2824 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2827 (GetLastError() == NTE_BAD_HASH_STATE ||
2828 GetLastError() == NTE_BAD_ALGID || /* Win9x */
2829 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
2830 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
2831 "got %08x\n", GetLastError());
2834 /* Finally, verifying the hash of a detached message in the correct order:
2835 * 1. Update with the detached hash message
2836 * 2. Update with the content of the message
2837 * 3. Verifying the hash of the message
2840 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2842 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
2844 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2845 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2846 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2847 SetLastError(0xdeadbeef);
2848 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2849 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2852 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2854 /* Can't verify the hash of a signed message */
2855 SetLastError(0xdeadbeef);
2856 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2857 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2858 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2859 /* Can't decrypt a signed message */
2860 SetLastError(0xdeadbeef);
2861 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2862 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2863 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2865 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2866 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2868 CryptMsgUpdate(msg, signedWithCertBareContent,
2869 sizeof(signedWithCertBareContent), TRUE);
2870 /* With an empty cert info, the signer can't be found in the message (and
2871 * the signature can't be verified.
2873 SetLastError(0xdeadbeef);
2874 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2875 ok(!ret && (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND ||
2876 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2877 "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n",
2879 /* The cert info is expected to have an issuer, serial number, and public
2882 certInfo.SerialNumber.cbData = sizeof(serialNum);
2883 certInfo.SerialNumber.pbData = serialNum;
2884 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2885 certInfo.Issuer.pbData = encodedCommonName;
2886 SetLastError(0xdeadbeef);
2887 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2888 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2889 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2890 "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError());
2892 /* This cert has a public key, but it's not in a usable form */
2893 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2895 ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2896 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2899 /* Crashes on some Win9x */
2900 /* Again, cert info needs to have a public key set */
2901 SetLastError(0xdeadbeef);
2902 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2904 (GetLastError() == CRYPT_E_ASN1_EOD ||
2905 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2906 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2907 /* The public key is supposed to be in encoded form.. */
2908 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2909 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2910 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2911 SetLastError(0xdeadbeef);
2912 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2914 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2915 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2916 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2917 /* but not as a X509_PUBLIC_KEY_INFO.. */
2918 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2919 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2920 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2921 SetLastError(0xdeadbeef);
2922 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2924 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2925 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2926 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2927 /* This decodes successfully, but it doesn't match any key in the message */
2928 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2929 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2930 SetLastError(0xdeadbeef);
2931 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2932 /* In Wine's rsaenh, this fails to decode because the key length is too
2933 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
2938 (GetLastError() == NTE_BAD_SIGNATURE ||
2939 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2940 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2943 /* A message with no data doesn't have a valid signature */
2944 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2945 ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2946 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2949 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2950 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2951 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2952 SetLastError(0xdeadbeef);
2953 /* Crashes on some Win9x */
2954 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2956 (GetLastError() == NTE_BAD_SIGNATURE ||
2957 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2958 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2961 /* Finally, this succeeds */
2962 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2963 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2964 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2965 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2966 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2967 "CryptMsgControl failed: %08x\n", GetLastError());
2970 /* Test verifying signature of a detached signed message */
2971 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2973 ret = CryptMsgUpdate(msg, detachedSignedContent,
2974 sizeof(detachedSignedContent), TRUE);
2975 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2976 /* Can't verify the sig without having updated the data */
2977 SetLastError(0xdeadbeef);
2978 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2979 ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
2980 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2981 "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n",
2983 /* Now that the signature's been checked, can't do the final update */
2984 SetLastError(0xdeadbeef);
2985 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2988 (GetLastError() == NTE_BAD_HASH_STATE ||
2989 GetLastError() == NTE_BAD_ALGID || /* Win9x */
2990 GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */
2991 broken(ret), /* Win9x */
2992 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
2993 "got %08x\n", GetLastError());
2995 /* Updating with the detached portion of the message and the data of the
2996 * the message allows the sig to be verified.
2998 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3000 ret = CryptMsgUpdate(msg, detachedSignedContent,
3001 sizeof(detachedSignedContent), TRUE);
3002 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3003 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3004 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3005 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3006 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3007 "CryptMsgControl failed: %08x\n", GetLastError());
3011 /* win9x has much less parameter checks and will crash on many tests
3012 * this code is from test_signed_msg_update()
3014 static BOOL detect_nt(void)
3017 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
3018 CERT_INFO certInfo = { 0 };
3020 if (!pCryptAcquireContextW)
3023 certInfo.SerialNumber.cbData = sizeof(serialNum);
3024 certInfo.SerialNumber.pbData = serialNum;
3025 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3026 certInfo.Issuer.pbData = encodedCommonName;
3027 signer.pCertInfo = &certInfo;
3028 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3030 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3031 PROV_RSA_FULL, CRYPT_NEWKEYSET);
3032 if (!ret && GetLastError() == NTE_EXISTS) {
3033 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3037 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
3040 CryptReleaseContext(signer.hCryptProv, 0);
3041 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
3042 CRYPT_DELETEKEYSET);
3047 static void test_msg_get_and_verify_signer(void)
3051 PCCERT_CONTEXT signer;
3058 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
3059 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3062 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3063 /* An empty message has no signer */
3064 SetLastError(0xdeadbeef);
3065 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3066 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3067 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3068 /* The signer is cleared on error */
3069 signer = (PCCERT_CONTEXT)0xdeadbeef;
3070 SetLastError(0xdeadbeef);
3071 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3072 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3073 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3074 ok(!signer, "expected signer to be NULL\n");
3075 /* The signer index is also cleared on error */
3076 signerIndex = 0xdeadbeef;
3077 SetLastError(0xdeadbeef);
3078 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3079 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3080 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3081 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
3082 /* An unsigned message (msgData isn't a signed message at all)
3083 * likewise has no signer.
3085 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3086 SetLastError(0xdeadbeef);
3087 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3088 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3089 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3092 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3093 /* A "signed" message created with no signer cert likewise has no signer */
3094 ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
3097 /* Crashes on most Win9x */
3098 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3099 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3100 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3104 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3105 /* A signed message succeeds, .. */
3106 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3107 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3108 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3109 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3110 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3111 /* the signer index can be retrieved, .. */
3112 signerIndex = 0xdeadbeef;
3113 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3114 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3115 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3117 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
3118 /* as can the signer cert. */
3119 signer = (PCCERT_CONTEXT)0xdeadbeef;
3120 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3121 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3122 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3124 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3125 "expected a valid signer\n");
3126 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3127 CertFreeCertificateContext(signer);
3128 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3130 signerIndex = 0xdeadbeef;
3131 SetLastError(0xdeadbeef);
3132 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3133 NULL, &signerIndex);
3134 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3135 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3136 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3137 * message signer not to be found.
3139 SetLastError(0xdeadbeef);
3140 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3142 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3143 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3144 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3145 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3146 * the message signer not to be found.
3148 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3149 CERT_STORE_CREATE_NEW_FLAG, NULL);
3150 SetLastError(0xdeadbeef);
3151 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3153 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3154 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3155 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3156 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3157 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3158 CERT_STORE_ADD_ALWAYS, NULL);
3159 ok(ret, "CertAddEncodedCertificateToStore failed: 0x%08x\n",
3161 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3162 * the signer succeeds.
3164 SetLastError(0xdeadbeef);
3165 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3167 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3168 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3169 CertCloseStore(store, 0);
3175 init_function_pointers();
3176 have_nt = detect_nt();
3178 win_skip("Win9x crashes on some parameter checks\n");
3180 /* Basic parameter checking tests */
3181 test_msg_open_to_encode();
3182 test_msg_open_to_decode();
3183 test_msg_get_param();
3187 /* Message-type specific tests */
3193 test_msg_get_and_verify_signer();