2 * Unit test suite for crypt32.dll's CryptMsg functions
4 * Copyright 2007 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #define CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS
27 #define CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS
30 #include "wine/test.h"
32 static BOOL old_crypt32
= FALSE
;
33 static char oid_rsa_md5
[] = szOID_RSA_MD5
;
35 static void test_msg_open_to_encode(void)
40 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
42 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
44 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
49 SetLastError(0xdeadbeef);
50 msg
= CryptMsgOpenToEncode(0, 0, 0, NULL
, NULL
, NULL
);
51 ok(!msg
&& GetLastError() == E_INVALIDARG
,
52 "Expected E_INVALIDARG, got %lx\n", GetLastError());
53 SetLastError(0xdeadbeef);
54 msg
= CryptMsgOpenToEncode(X509_ASN_ENCODING
, 0, 0, NULL
, NULL
, NULL
);
55 ok(!msg
&& GetLastError() == E_INVALIDARG
,
56 "Expected E_INVALIDARG, got %lx\n", GetLastError());
58 /* Bad message types */
59 SetLastError(0xdeadbeef);
60 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, 0, NULL
, NULL
, NULL
);
61 ok(!msg
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
62 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
63 SetLastError(0xdeadbeef);
64 msg
= CryptMsgOpenToEncode(X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
, 0, 0,
66 ok(!msg
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
67 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
68 SetLastError(0xdeadbeef);
69 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0,
70 CMSG_SIGNED_AND_ENVELOPED
, NULL
, NULL
, NULL
);
71 ok(!msg
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
72 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
73 SetLastError(0xdeadbeef);
74 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENCRYPTED
, NULL
,
76 ok(!msg
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
77 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
80 static void test_msg_open_to_decode(void)
83 CMSG_STREAM_INFO streamInfo
= { 0 };
85 SetLastError(0xdeadbeef);
86 msg
= CryptMsgOpenToDecode(0, 0, 0, 0, NULL
, NULL
);
87 ok(!msg
&& GetLastError() == E_INVALIDARG
,
88 "Expected E_INVALIDARG, got %lx\n", GetLastError());
91 SetLastError(0xdeadbeef);
92 msg
= CryptMsgOpenToDecode(X509_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
93 ok(!msg
&& GetLastError() == E_INVALIDARG
,
94 "Expected E_INVALIDARG, got %lx\n", GetLastError());
95 SetLastError(0xdeadbeef);
96 msg
= CryptMsgOpenToDecode(X509_ASN_ENCODING
, 0, CMSG_DATA
, 0, NULL
, NULL
);
97 ok(!msg
&& GetLastError() == E_INVALIDARG
,
98 "Expected E_INVALIDARG, got %lx\n", GetLastError());
100 /* The message type can be explicit... */
101 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, 0, NULL
,
103 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
105 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
, 0, NULL
,
107 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
109 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
111 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
113 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, 0, NULL
,
115 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
117 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0,
118 CMSG_SIGNED_AND_ENVELOPED
, 0, NULL
, NULL
);
119 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
122 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
123 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
125 /* or even invalid. */
126 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENCRYPTED
, 0, NULL
,
128 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
130 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 1000, 0, NULL
, NULL
);
131 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
134 /* And even though the stream info parameter "must be set to NULL" for
135 * CMSG_HASHED, it's still accepted.
137 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
139 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
143 static void test_msg_get_param(void)
147 DWORD size
, i
, value
;
150 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
151 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
152 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
155 /* Decoded messages */
156 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
157 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
158 /* For decoded messages, the type is always available */
160 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, NULL
, &size
);
161 ok(ret
, "CryptMsgGetParam failed: %lx\n", GetLastError());
162 size
= sizeof(value
);
163 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &value
, &size
);
164 ok(ret
, "CryptMsgGetParam failed: %lx\n", GetLastError());
165 /* For this (empty) message, the type isn't set */
166 ok(value
== 0, "Expected type 0, got %ld\n", value
);
169 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, 0, NULL
,
171 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
172 /* For explicitly typed messages, the type is known. */
173 size
= sizeof(value
);
174 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &value
, &size
);
175 ok(ret
, "CryptMsgGetParam failed: %lx\n", GetLastError());
176 ok(value
== CMSG_DATA
, "Expected CMSG_DATA, got %ld\n", value
);
177 for (i
= CMSG_CONTENT_PARAM
; !old_crypt32
&& (i
<= CMSG_CMS_SIGNER_INFO_PARAM
); i
++)
180 ret
= CryptMsgGetParam(msg
, i
, 0, NULL
, &size
);
181 ok(!ret
, "Parameter %ld: expected failure\n", i
);
185 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
, 0, NULL
,
187 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
188 size
= sizeof(value
);
189 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &value
, &size
);
190 ok(ret
, "CryptMsgGetParam failed: %lx\n", GetLastError());
191 ok(value
== CMSG_ENVELOPED
, "Expected CMSG_ENVELOPED, got %ld\n", value
);
192 for (i
= CMSG_CONTENT_PARAM
; !old_crypt32
&& (i
<= CMSG_CMS_SIGNER_INFO_PARAM
); i
++)
195 ret
= CryptMsgGetParam(msg
, i
, 0, NULL
, &size
);
196 ok(!ret
, "Parameter %ld: expected failure\n", i
);
200 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
202 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
203 size
= sizeof(value
);
204 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &value
, &size
);
205 ok(ret
, "CryptMsgGetParam failed: %lx\n", GetLastError());
206 ok(value
== CMSG_HASHED
, "Expected CMSG_HASHED, got %ld\n", value
);
207 for (i
= CMSG_CONTENT_PARAM
; !old_crypt32
&& (i
<= CMSG_CMS_SIGNER_INFO_PARAM
); i
++)
210 ret
= CryptMsgGetParam(msg
, i
, 0, NULL
, &size
);
211 ok(!ret
, "Parameter %ld: expected failure\n", i
);
215 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, 0, NULL
,
217 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
218 size
= sizeof(value
);
219 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &value
, &size
);
220 ok(ret
, "CryptMsgGetParam failed: %lx\n", GetLastError());
221 ok(value
== CMSG_SIGNED
, "Expected CMSG_SIGNED, got %ld\n", value
);
222 for (i
= CMSG_CONTENT_PARAM
; !old_crypt32
&& (i
<= CMSG_CMS_SIGNER_INFO_PARAM
); i
++)
225 ret
= CryptMsgGetParam(msg
, i
, 0, NULL
, &size
);
226 ok(!ret
, "Parameter %ld: expected failure\n", i
);
230 /* Explicitly typed messages get their types set, even if they're invalid */
231 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENCRYPTED
, 0, NULL
,
233 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
234 size
= sizeof(value
);
235 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &value
, &size
);
236 ok(ret
, "CryptMsgGetParam failed: %lx\n", GetLastError());
237 ok(value
== CMSG_ENCRYPTED
, "Expected CMSG_ENCRYPTED, got %ld\n", value
);
240 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 1000, 0, NULL
, NULL
);
241 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
242 size
= sizeof(value
);
243 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &value
, &size
);
244 ok(ret
, "CryptMsgGetParam failed: %lx\n", GetLastError());
245 ok(value
== 1000, "Expected 1000, got %ld\n", value
);
249 static void test_msg_close(void)
254 /* NULL succeeds.. */
255 ret
= CryptMsgClose(NULL
);
256 ok(ret
, "CryptMsgClose failed: %lx\n", GetLastError());
257 /* but an arbitrary pointer crashes. */
259 ret
= CryptMsgClose((HCRYPTMSG
)1);
260 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
262 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
263 ret
= CryptMsgClose(msg
);
264 ok(ret
, "CryptMsgClose failed: %lx\n", GetLastError());
267 static void check_param(LPCSTR test
, HCRYPTMSG msg
, DWORD param
,
268 const BYTE
*expected
, DWORD expectedSize
)
275 ret
= CryptMsgGetParam(msg
, param
, 0, NULL
, &size
);
276 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */ ||
277 GetLastError() == CRYPT_E_INVALID_MSG_TYPE
/* Win9x, for some params */),
278 "%s: CryptMsgGetParam failed: %08lx\n", test
, GetLastError());
281 win_skip("parameter %ld not supported, skipping tests\n", param
);
284 buf
= HeapAlloc(GetProcessHeap(), 0, size
);
285 ret
= CryptMsgGetParam(msg
, param
, 0, buf
, &size
);
286 ok(ret
, "%s: CryptMsgGetParam failed: %08lx\n", test
, GetLastError());
287 ok(size
== expectedSize
, "%s: expected size %ld, got %ld\n", test
,
289 if (size
== expectedSize
&& size
)
290 ok(!memcmp(buf
, expected
, size
), "%s: unexpected data\n", test
);
291 HeapFree(GetProcessHeap(), 0, buf
);
294 static void test_data_msg_open(void)
297 CMSG_HASHED_ENCODE_INFO hashInfo
= { 0 };
298 CMSG_STREAM_INFO streamInfo
= { 0 };
299 char oid
[] = "1.2.3";
301 /* The data message type takes no additional info */
302 SetLastError(0xdeadbeef);
303 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, &hashInfo
,
305 ok(!msg
&& GetLastError() == E_INVALIDARG
,
306 "Expected E_INVALIDARG, got %lx\n", GetLastError());
307 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
309 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
312 /* An empty stream info is allowed. */
313 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
315 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
318 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
319 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, oid
,
321 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
323 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
324 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
325 CMSG_DATA
, NULL
, oid
, NULL
);
326 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
328 /* and when a stream info is given, even though you're not supposed to be
329 * able to use anything but szOID_RSA_data when streaming is being used.
331 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
332 CMSG_DATA
, NULL
, oid
, &streamInfo
);
333 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
337 static const BYTE msgData
[] = { 1, 2, 3, 4 };
339 static BOOL WINAPI
nop_stream_output(const void *pvArg
, BYTE
*pb
, DWORD cb
,
345 static const BYTE dataEmptyBareContent
[] = { 0x04,0x00 };
347 static void test_data_msg_update(void)
351 CMSG_STREAM_INFO streamInfo
= { 0 };
353 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
355 /* Can't update a message that wasn't opened detached with final = FALSE */
356 SetLastError(0xdeadbeef);
357 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
358 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
359 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
360 /* Updating it with final = TRUE succeeds */
361 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
362 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
363 /* Any subsequent update will fail, as the last was final */
364 SetLastError(0xdeadbeef);
365 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
366 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
367 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
370 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
372 /* Starting with Vista, can update a message with no data. */
373 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
374 ok(ret
|| broken(!ret
), "CryptMsgUpdate failed: %08lx\n", GetLastError());
379 ret
= CryptMsgGetParam(msg
, CMSG_BARE_CONTENT_PARAM
, 0, NULL
, &size
);
380 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
383 LPBYTE buf
= CryptMemAlloc(size
);
387 ret
= CryptMsgGetParam(msg
, CMSG_BARE_CONTENT_PARAM
, 0, buf
,
389 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
392 ok(size
== sizeof(dataEmptyBareContent
),
393 "unexpected size %ld\n", size
);
394 ok(!memcmp(buf
, dataEmptyBareContent
, size
),
395 "unexpected value\n");
403 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
404 CMSG_DATA
, NULL
, NULL
, NULL
);
406 SetLastError(0xdeadbeef);
407 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
409 (GetLastError() == E_INVALIDARG
||
410 broken(GetLastError() == ERROR_SUCCESS
)), /* Older NT4 */
411 "Expected E_INVALIDARG, got %lx\n", GetLastError());
412 SetLastError(0xdeadbeef);
413 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
415 (GetLastError() == E_INVALIDARG
||
416 broken(GetLastError() == ERROR_SUCCESS
)), /* Older NT4 */
417 "Expected E_INVALIDARG, got %lx\n", GetLastError());
419 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
420 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
425 /* Calling update after opening with an empty stream info (with a bogus
426 * output function) yields an error:
428 /* Crashes on some Win9x */
429 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
431 SetLastError(0xdeadbeef);
432 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
433 ok(!ret
&& (GetLastError() == STATUS_ACCESS_VIOLATION
||
434 GetLastError() == STATUS_ILLEGAL_INSTRUCTION
/* WinME */),
435 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %lx\n",
439 /* Calling update with a valid output function succeeds, even if the data
440 * exceeds the size specified in the stream info.
442 streamInfo
.pfnStreamOutput
= nop_stream_output
;
443 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
445 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
446 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
447 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
448 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
452 static void test_data_msg_get_param(void)
457 CMSG_STREAM_INFO streamInfo
= { 0, nop_stream_output
, NULL
};
459 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
462 /* Content and bare content are always gettable when not streaming */
464 ret
= CryptMsgGetParam(msg
, CMSG_CONTENT_PARAM
, 0, NULL
, &size
);
465 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
467 ret
= CryptMsgGetParam(msg
, CMSG_BARE_CONTENT_PARAM
, 0, NULL
, &size
);
468 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
469 /* But for this type of message, the signer and hash aren't applicable,
470 * and the type isn't available.
473 SetLastError(0xdeadbeef);
474 ret
= CryptMsgGetParam(msg
, CMSG_ENCODED_SIGNER
, 0, NULL
, &size
);
475 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
476 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
477 SetLastError(0xdeadbeef);
478 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, NULL
, &size
);
479 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
480 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
481 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, NULL
, &size
);
482 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
483 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
486 /* Can't get content or bare content when streaming */
487 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
,
489 SetLastError(0xdeadbeef);
490 ret
= CryptMsgGetParam(msg
, CMSG_BARE_CONTENT_PARAM
, 0, NULL
, &size
);
491 ok((!ret
&& GetLastError() == E_INVALIDARG
) || broken(ret
/* Win9x */),
492 "Expected E_INVALIDARG, got %lx\n", GetLastError());
493 SetLastError(0xdeadbeef);
494 ret
= CryptMsgGetParam(msg
, CMSG_CONTENT_PARAM
, 0, NULL
, &size
);
495 ok((!ret
&& GetLastError() == E_INVALIDARG
) || broken(ret
/* Win9x */),
496 "Expected E_INVALIDARG, got %lx\n", GetLastError());
500 static const BYTE dataEmptyContent
[] = {
501 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
503 static const BYTE dataBareContent
[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
504 static const BYTE dataContent
[] = {
505 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
506 0x04,0x04,0x01,0x02,0x03,0x04 };
511 CRYPT_DATA_BLOB
*updates
;
514 static BOOL WINAPI
accumulating_stream_output(const void *pvArg
, BYTE
*pb
,
515 DWORD cb
, BOOL final
)
517 struct update_accum
*accum
= (struct update_accum
*)pvArg
;
521 accum
->updates
= CryptMemRealloc(accum
->updates
,
522 (accum
->cUpdates
+ 1) * sizeof(CRYPT_DATA_BLOB
));
524 accum
->updates
= CryptMemAlloc(sizeof(CRYPT_DATA_BLOB
));
527 CRYPT_DATA_BLOB
*blob
= &accum
->updates
[accum
->cUpdates
];
529 blob
->pbData
= CryptMemAlloc(cb
);
532 memcpy(blob
->pbData
, pb
, cb
);
541 /* The updates of a (bogus) definite-length encoded message */
542 static BYTE u1
[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
543 0x07,0x01,0xa0,0x02,0x04,0x00 };
544 static BYTE u2
[] = { 0x01,0x02,0x03,0x04 };
545 static CRYPT_DATA_BLOB b1
[] = {
550 static const struct update_accum a1
= { ARRAY_SIZE(b1
), b1
};
551 /* The updates of a definite-length encoded message */
552 static BYTE u3
[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
553 0x07,0x01,0xa0,0x06,0x04,0x04 };
554 static CRYPT_DATA_BLOB b2
[] = {
558 static const struct update_accum a2
= { ARRAY_SIZE(b2
), b2
};
559 /* The updates of an indefinite-length encoded message */
560 static BYTE u4
[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
561 0x07,0x01,0xa0,0x80,0x24,0x80 };
562 static BYTE u5
[] = { 0x04,0x04 };
563 static BYTE u6
[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
564 static CRYPT_DATA_BLOB b3
[] = {
572 static const struct update_accum a3
= { ARRAY_SIZE(b3
), b3
};
574 static void check_updates(LPCSTR header
, const struct update_accum
*expected
,
575 const struct update_accum
*got
)
579 ok(expected
->cUpdates
== got
->cUpdates
,
580 "%s: expected %ld updates, got %ld\n", header
, expected
->cUpdates
,
582 if (expected
->cUpdates
== got
->cUpdates
)
583 for (i
= 0; i
< min(expected
->cUpdates
, got
->cUpdates
); i
++)
585 ok(expected
->updates
[i
].cbData
== got
->updates
[i
].cbData
,
586 "%s, update %ld: expected %ld bytes, got %ld\n", header
, i
,
587 expected
->updates
[i
].cbData
, got
->updates
[i
].cbData
);
588 if (expected
->updates
[i
].cbData
&& expected
->updates
[i
].cbData
==
589 got
->updates
[i
].cbData
)
590 ok(!memcmp(expected
->updates
[i
].pbData
, got
->updates
[i
].pbData
,
591 got
->updates
[i
].cbData
), "%s, update %ld: unexpected value\n",
596 /* Frees the updates stored in accum */
597 static void free_updates(struct update_accum
*accum
)
601 for (i
= 0; i
< accum
->cUpdates
; i
++)
602 CryptMemFree(accum
->updates
[i
].pbData
);
603 CryptMemFree(accum
->updates
);
604 accum
->updates
= NULL
;
608 static void test_data_msg_encoding(void)
612 static char oid
[] = "1.2.3";
613 struct update_accum accum
= { 0, NULL
};
614 CMSG_STREAM_INFO streamInfo
= { 0, accumulating_stream_output
, &accum
};
616 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
618 check_param("data empty bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
619 dataEmptyBareContent
, sizeof(dataEmptyBareContent
));
620 check_param("data empty content", msg
, CMSG_CONTENT_PARAM
, dataEmptyContent
,
621 sizeof(dataEmptyContent
));
622 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
623 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
624 check_param("data bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
625 dataBareContent
, sizeof(dataBareContent
));
626 check_param("data content", msg
, CMSG_CONTENT_PARAM
, dataContent
,
627 sizeof(dataContent
));
629 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
630 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_BARE_CONTENT_FLAG
,
631 CMSG_DATA
, NULL
, NULL
, NULL
);
632 check_param("data empty bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
633 dataEmptyBareContent
, sizeof(dataEmptyBareContent
));
634 check_param("data empty content", msg
, CMSG_CONTENT_PARAM
, dataEmptyContent
,
635 sizeof(dataEmptyContent
));
636 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
637 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
638 check_param("data bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
639 dataBareContent
, sizeof(dataBareContent
));
640 check_param("data content", msg
, CMSG_CONTENT_PARAM
, dataContent
,
641 sizeof(dataContent
));
643 /* The inner OID is apparently ignored */
644 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, oid
,
646 check_param("data bogus oid bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
647 dataEmptyBareContent
, sizeof(dataEmptyBareContent
));
648 check_param("data bogus oid content", msg
, CMSG_CONTENT_PARAM
,
649 dataEmptyContent
, sizeof(dataEmptyContent
));
650 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
651 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
652 check_param("data bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
653 dataBareContent
, sizeof(dataBareContent
));
654 check_param("data content", msg
, CMSG_CONTENT_PARAM
, dataContent
,
655 sizeof(dataContent
));
657 /* A streaming message is DER encoded if the length is not 0xffffffff, but
658 * curiously, updates aren't validated to make sure they don't exceed the
659 * stated length. (The resulting output will of course fail to decode.)
661 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
,
663 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
664 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
666 check_updates("bogus data message with definite length", &a1
, &accum
);
667 free_updates(&accum
);
668 /* A valid definite-length encoding: */
669 streamInfo
.cbContent
= sizeof(msgData
);
670 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
,
672 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
674 check_updates("data message with definite length", &a2
, &accum
);
675 free_updates(&accum
);
676 /* An indefinite-length encoding: */
677 streamInfo
.cbContent
= 0xffffffff;
678 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
,
680 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
681 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
683 check_updates("data message with indefinite length", &a3
, &accum
);
684 free_updates(&accum
);
687 static void test_data_msg(void)
689 test_data_msg_open();
690 test_data_msg_update();
691 test_data_msg_get_param();
692 test_data_msg_encoding();
695 static void test_hash_msg_open(void)
698 CMSG_HASHED_ENCODE_INFO hashInfo
= { 0 };
699 CMSG_STREAM_INFO streamInfo
= { 0, nop_stream_output
, NULL
};
701 SetLastError(0xdeadbeef);
702 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
704 ok(!msg
&& GetLastError() == E_INVALIDARG
,
705 "Expected E_INVALIDARG, got %lx\n", GetLastError());
706 hashInfo
.cbSize
= sizeof(hashInfo
);
707 SetLastError(0xdeadbeef);
708 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
710 ok(!msg
&& GetLastError() == CRYPT_E_UNKNOWN_ALGO
,
711 "Expected CRYPT_E_UNKNOWN_ALGO, got %lx\n", GetLastError());
712 hashInfo
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
713 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
715 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
717 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
718 CMSG_HASHED
, &hashInfo
, NULL
, NULL
);
719 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
721 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
722 CMSG_HASHED
, &hashInfo
, NULL
, &streamInfo
);
723 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
727 static void test_hash_msg_update(void)
731 CMSG_HASHED_ENCODE_INFO hashInfo
= { sizeof(hashInfo
), 0,
732 { oid_rsa_md5
, { 0, NULL
} }, NULL
};
733 CMSG_STREAM_INFO streamInfo
= { 0, nop_stream_output
, NULL
};
735 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
736 CMSG_HASHED
, &hashInfo
, NULL
, NULL
);
737 /* Detached hashed messages opened in non-streaming mode allow non-final
740 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
741 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
742 /* including non-final updates with no data.. */
743 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
744 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
745 /* and final updates with no data. */
746 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
747 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
748 /* But no updates are allowed after the final update. */
749 SetLastError(0xdeadbeef);
750 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
751 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
752 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
753 SetLastError(0xdeadbeef);
754 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
755 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
756 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
758 /* Non-detached messages, in contrast, don't allow non-final updates in
759 * non-streaming mode.
761 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
763 SetLastError(0xdeadbeef);
764 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
765 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
766 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
767 /* Final updates (including empty ones) are allowed. */
768 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
769 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
771 /* And, of course, streaming mode allows non-final updates */
772 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
774 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
775 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
777 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
778 * to be a bug, it isn't actually used - see encoding tests.)
780 streamInfo
.pfnStreamOutput
= NULL
;
781 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
783 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
784 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
788 static const BYTE emptyHashParam
[] = {
789 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
792 static void test_hash_msg_get_param(void)
796 CMSG_HASHED_ENCODE_INFO hashInfo
= { sizeof(hashInfo
), 0,
797 { oid_rsa_md5
, { 0, NULL
} }, NULL
};
799 CMSG_STREAM_INFO streamInfo
= { 0, nop_stream_output
, NULL
};
802 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
804 /* Content and bare content are always gettable for non-streamed messages */
806 ret
= CryptMsgGetParam(msg
, CMSG_CONTENT_PARAM
, 0, NULL
, &size
);
807 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
808 "CryptMsgGetParam failed: %08lx\n", GetLastError());
810 ret
= CryptMsgGetParam(msg
, CMSG_BARE_CONTENT_PARAM
, 0, NULL
, &size
);
811 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
812 "CryptMsgGetParam failed: %08lx\n", GetLastError());
813 /* For an encoded hash message, the hash data aren't available */
814 SetLastError(0xdeadbeef);
815 ret
= CryptMsgGetParam(msg
, CMSG_HASH_DATA_PARAM
, 0, NULL
, &size
);
816 ok(!ret
&& (GetLastError() == CRYPT_E_INVALID_MSG_TYPE
||
817 GetLastError() == OSS_LIMITED
/* Win9x */),
818 "Expected CRYPT_E_INVALID_MSG_TYPE or OSS_LIMITED, got %08lx\n",
820 /* The hash is also available. */
822 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, NULL
, &size
);
823 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
824 ok(size
== sizeof(buf
), "Unexpected size %ld\n", size
);
825 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, buf
, &size
);
826 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
827 ok(size
== sizeof(buf
), "Unexpected size %ld\n", size
);
828 if (size
== sizeof(buf
))
829 ok(!memcmp(buf
, emptyHashParam
, size
), "Unexpected value\n");
830 /* By getting the hash, further updates are not allowed */
831 SetLastError(0xdeadbeef);
832 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
834 (GetLastError() == NTE_BAD_HASH_STATE
/* NT */ ||
835 GetLastError() == NTE_BAD_ALGID
/* 9x */ ||
836 GetLastError() == CRYPT_E_MSG_ERROR
/* Vista */ ||
837 broken(GetLastError() == ERROR_SUCCESS
) /* Some Win9x */),
838 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%lx\n", GetLastError());
840 /* Even after a final update, the hash data aren't available */
841 SetLastError(0xdeadbeef);
842 ret
= CryptMsgGetParam(msg
, CMSG_HASH_DATA_PARAM
, 0, NULL
, &size
);
843 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
844 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
845 /* The version is also available, and should be zero for this message. */
847 ret
= CryptMsgGetParam(msg
, CMSG_VERSION_PARAM
, 0, NULL
, &size
);
848 ok(ret
|| broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE
/* Win9x */),
849 "CryptMsgGetParam failed: %08lx\n", GetLastError());
850 size
= sizeof(value
);
851 ret
= CryptMsgGetParam(msg
, CMSG_VERSION_PARAM
, 0, &value
, &size
);
852 ok(ret
|| broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE
/* Win9x */),
853 "CryptMsgGetParam failed: %08lx\n", GetLastError());
855 ok(value
== 0, "Expected version 0, got %ld\n", value
);
856 /* As usual, the type isn't available. */
857 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, NULL
, &size
);
858 ok(!ret
, "Expected failure\n");
861 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
863 /* Streamed messages don't allow you to get the content or bare content. */
864 SetLastError(0xdeadbeef);
865 ret
= CryptMsgGetParam(msg
, CMSG_CONTENT_PARAM
, 0, NULL
, &size
);
866 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
867 GetLastError() == OSS_LIMITED
/* Win9x */),
868 "Expected E_INVALIDARG or OSS_LIMITED, got %lx\n", GetLastError());
869 SetLastError(0xdeadbeef);
870 ret
= CryptMsgGetParam(msg
, CMSG_BARE_CONTENT_PARAM
, 0, NULL
, &size
);
871 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
872 GetLastError() == OSS_LIMITED
/* Win9x */),
873 "Expected E_INVALIDARG or OSS_LIMITED, got %lx\n", GetLastError());
874 /* The hash is still available. */
876 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, NULL
, &size
);
877 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
878 ok(size
== sizeof(buf
), "Unexpected size %ld\n", size
);
879 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, buf
, &size
);
880 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
881 if (size
== sizeof(buf
))
882 ok(!memcmp(buf
, emptyHashParam
, size
), "Unexpected value\n");
883 /* After updating the hash, further updates aren't allowed on streamed
886 SetLastError(0xdeadbeef);
887 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
889 (GetLastError() == NTE_BAD_HASH_STATE
/* NT */ ||
890 GetLastError() == NTE_BAD_ALGID
/* 9x */ ||
891 GetLastError() == CRYPT_E_MSG_ERROR
/* Vista */ ||
892 broken(GetLastError() == ERROR_SUCCESS
) /* Some Win9x */),
893 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%lx\n", GetLastError());
898 static const BYTE hashEmptyBareContent
[] = {
899 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
900 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
901 static const BYTE hashEmptyContent
[] = {
902 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
903 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
904 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
905 static const BYTE hashBareContent
[] = {
906 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
907 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
908 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
909 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
910 static const BYTE hashContent
[] = {
911 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
912 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
913 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
914 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
915 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
917 static const BYTE detachedHashNonFinalBareContent
[] = {
918 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
919 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
920 0x07,0x01,0x04,0x00 };
921 static const BYTE detachedHashNonFinalContent
[] = {
922 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
923 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
924 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
925 0x07,0x01,0x04,0x00 };
926 static const BYTE detachedHashBareContent
[] = {
927 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
928 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
929 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
930 0x9d,0x2a,0x8f,0x26,0x2f };
931 static const BYTE detachedHashContent
[] = {
932 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
933 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
934 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
935 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
936 0x9d,0x2a,0x8f,0x26,0x2f };
938 static void test_hash_msg_encoding(void)
941 CMSG_HASHED_ENCODE_INFO hashInfo
= { sizeof(hashInfo
), 0 };
943 struct update_accum accum
= { 0, NULL
}, empty_accum
= { 0, NULL
};
944 CMSG_STREAM_INFO streamInfo
= { 0, accumulating_stream_output
, &accum
};
946 hashInfo
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
947 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
949 check_param("hash empty bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
950 hashEmptyBareContent
, sizeof(hashEmptyBareContent
));
951 check_param("hash empty content", msg
, CMSG_CONTENT_PARAM
,
952 hashEmptyContent
, sizeof(hashEmptyContent
));
953 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
954 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
955 check_param("hash bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
956 hashBareContent
, sizeof(hashBareContent
));
957 check_param("hash content", msg
, CMSG_CONTENT_PARAM
,
958 hashContent
, sizeof(hashContent
));
960 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
961 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_BARE_CONTENT_FLAG
,
962 CMSG_HASHED
, &hashInfo
, NULL
, NULL
);
963 check_param("hash empty bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
964 hashEmptyBareContent
, sizeof(hashEmptyBareContent
));
965 check_param("hash empty content", msg
, CMSG_CONTENT_PARAM
,
966 hashEmptyContent
, sizeof(hashEmptyContent
));
967 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
968 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
969 check_param("hash bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
970 hashBareContent
, sizeof(hashBareContent
));
971 check_param("hash content", msg
, CMSG_CONTENT_PARAM
,
972 hashContent
, sizeof(hashContent
));
974 /* Same test, but with CMSG_DETACHED_FLAG set */
975 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
976 CMSG_HASHED
, &hashInfo
, NULL
, NULL
);
977 check_param("detached hash empty bare content", msg
,
978 CMSG_BARE_CONTENT_PARAM
, hashEmptyBareContent
,
979 sizeof(hashEmptyBareContent
));
980 check_param("detached hash empty content", msg
, CMSG_CONTENT_PARAM
,
981 hashEmptyContent
, sizeof(hashEmptyContent
));
982 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
983 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
984 check_param("detached hash not final bare content", msg
,
985 CMSG_BARE_CONTENT_PARAM
, detachedHashNonFinalBareContent
,
986 sizeof(detachedHashNonFinalBareContent
));
987 check_param("detached hash not final content", msg
, CMSG_CONTENT_PARAM
,
988 detachedHashNonFinalContent
, sizeof(detachedHashNonFinalContent
));
989 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
990 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
991 check_param("detached hash bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
992 detachedHashBareContent
, sizeof(detachedHashBareContent
));
993 check_param("detached hash content", msg
, CMSG_CONTENT_PARAM
,
994 detachedHashContent
, sizeof(detachedHashContent
));
995 check_param("detached hash bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
996 detachedHashBareContent
, sizeof(detachedHashBareContent
));
997 check_param("detached hash content", msg
, CMSG_CONTENT_PARAM
,
998 detachedHashContent
, sizeof(detachedHashContent
));
1000 /* In what appears to be a bug, streamed updates to hash messages don't
1001 * call the output function.
1003 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
1005 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
1006 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1007 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1008 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1010 check_updates("empty hash message", &empty_accum
, &accum
);
1011 free_updates(&accum
);
1013 streamInfo
.cbContent
= sizeof(msgData
);
1014 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
1016 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1017 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1019 check_updates("hash message", &empty_accum
, &accum
);
1020 free_updates(&accum
);
1022 streamInfo
.cbContent
= sizeof(msgData
);
1023 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
1024 CMSG_HASHED
, &hashInfo
, NULL
, &streamInfo
);
1025 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1026 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1028 check_updates("detached hash message", &empty_accum
, &accum
);
1029 free_updates(&accum
);
1032 static void test_hash_msg(void)
1034 test_hash_msg_open();
1035 test_hash_msg_update();
1036 test_hash_msg_get_param();
1037 test_hash_msg_encoding();
1040 static const CHAR cspNameA
[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1042 static BYTE serialNum
[] = { 1 };
1043 static BYTE encodedCommonName
[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1044 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1046 static void test_signed_msg_open(void)
1050 CMSG_SIGNED_ENCODE_INFO signInfo
= { 0 };
1051 CMSG_SIGNER_ENCODE_INFO signer
= { sizeof(signer
), 0 };
1052 CERT_INFO certInfo
= { 0 };
1054 SetLastError(0xdeadbeef);
1055 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1057 ok(!msg
&& GetLastError() == E_INVALIDARG
,
1058 "Expected E_INVALIDARG, got %lx\n", GetLastError());
1059 signInfo
.cbSize
= sizeof(signInfo
);
1060 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1062 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1065 signInfo
.cSigners
= 1;
1066 signInfo
.rgSigners
= &signer
;
1067 /* With signer.pCertInfo unset, attempting to open this message this
1070 signer
.pCertInfo
= &certInfo
;
1071 /* The cert info must contain a serial number and an issuer. */
1072 SetLastError(0xdeadbeef);
1073 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1075 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1076 ok(!msg
&& (GetLastError() == E_INVALIDARG
|| GetLastError() == 0xdeadbeef
1077 || GetLastError() == CRYPT_E_UNKNOWN_ALGO
),
1078 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%lx\n",
1081 certInfo
.SerialNumber
.cbData
= sizeof(serialNum
);
1082 certInfo
.SerialNumber
.pbData
= serialNum
;
1083 SetLastError(0xdeadbeef);
1084 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1086 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1087 ok(!msg
&& (GetLastError() == E_INVALIDARG
|| GetLastError() == 0xdeadbeef
1088 || GetLastError() == CRYPT_E_UNKNOWN_ALGO
),
1089 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%lx\n",
1092 certInfo
.Issuer
.cbData
= sizeof(encodedCommonName
);
1093 certInfo
.Issuer
.pbData
= encodedCommonName
;
1094 SetLastError(0xdeadbeef);
1095 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1097 ok(!msg
&& (GetLastError() == E_INVALIDARG
||
1098 GetLastError() == CRYPT_E_UNKNOWN_ALGO
),
1099 "Expected E_INVALIDARG or CRYPT_E_UNKNOWN_ALGO, got %lx\n", GetLastError());
1101 /* The signer's hCryptProv must be set to something. Whether it's usable
1102 * or not will be checked after the hash algorithm is checked (see next
1105 signer
.hCryptProv
= 1;
1106 SetLastError(0xdeadbeef);
1107 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1109 ok(!msg
&& GetLastError() == CRYPT_E_UNKNOWN_ALGO
,
1110 "Expected CRYPT_E_UNKNOWN_ALGO, got %lx\n", GetLastError());
1111 /* The signer's hash algorithm must also be set. */
1112 signer
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
1113 SetLastError(0xdeadbeef);
1114 /* Crashes in advapi32 in wine, don't do it */
1116 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
,
1117 &signInfo
, NULL
, NULL
);
1118 ok(!msg
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1119 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1121 /* The signer's hCryptProv must also be valid. */
1122 ret
= CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
,
1123 PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
1124 if (!ret
&& GetLastError() == NTE_EXISTS
) {
1125 ret
= CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
,
1128 ok(ret
, "CryptAcquireContext failed: 0x%lx\n", GetLastError());
1131 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1133 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1137 /* pCertInfo must still be set, but can be empty if the SignerId's issuer
1138 * and serial number are set.
1140 certInfo
.Issuer
.cbData
= 0;
1141 certInfo
.SerialNumber
.cbData
= 0;
1142 signer
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
1143 U(signer
.SignerId
).IssuerSerialNumber
.Issuer
.cbData
=
1144 sizeof(encodedCommonName
);
1145 U(signer
.SignerId
).IssuerSerialNumber
.Issuer
.pbData
= encodedCommonName
;
1146 U(signer
.SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
=
1148 U(signer
.SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
= serialNum
;
1149 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1151 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1154 CryptReleaseContext(signer
.hCryptProv
, 0);
1155 CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, MS_DEF_PROV_A
,
1156 PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
1159 static const BYTE privKey
[] = {
1160 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1161 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1162 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1163 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1164 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1165 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1166 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1167 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1168 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1169 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1170 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1171 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1172 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1173 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1174 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1175 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1176 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1177 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1178 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1179 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1180 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1181 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1182 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1183 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1184 static BYTE pubKey
[] = {
1185 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1186 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1187 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1188 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1189 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1191 static void test_signed_msg_update(void)
1195 CMSG_SIGNED_ENCODE_INFO signInfo
= { sizeof(signInfo
), 0 };
1196 CMSG_SIGNER_ENCODE_INFO signer
= { sizeof(signer
), 0 };
1197 CERT_INFO certInfo
= { 0 };
1200 certInfo
.SerialNumber
.cbData
= sizeof(serialNum
);
1201 certInfo
.SerialNumber
.pbData
= serialNum
;
1202 certInfo
.Issuer
.cbData
= sizeof(encodedCommonName
);
1203 certInfo
.Issuer
.pbData
= encodedCommonName
;
1204 signer
.pCertInfo
= &certInfo
;
1205 signer
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
1206 signInfo
.cSigners
= 1;
1207 signInfo
.rgSigners
= &signer
;
1209 ret
= CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
,
1210 PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
1211 if (!ret
&& GetLastError() == NTE_EXISTS
) {
1212 ret
= CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
,
1215 ok(ret
, "CryptAcquireContext failed: 0x%lx\n", GetLastError());
1218 skip("No context for tests\n");
1222 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
,
1223 CMSG_DETACHED_FLAG
, CMSG_SIGNED
, &signInfo
, NULL
, NULL
);
1224 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1225 /* Detached CMSG_SIGNED allows non-final updates. */
1226 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
1227 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1228 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1229 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
1230 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1231 /* The final update requires a private key in the hCryptProv, in order to
1232 * generate the signature.
1234 SetLastError(0xdeadbeef);
1235 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1237 (GetLastError() == NTE_BAD_KEYSET
||
1238 GetLastError() == NTE_NO_KEY
||
1239 broken(GetLastError() == ERROR_SUCCESS
)), /* Some Win9x */
1240 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %lx\n", GetLastError());
1241 ret
= CryptImportKey(signer
.hCryptProv
, privKey
, sizeof(privKey
),
1243 ok(ret
, "CryptImportKey failed: %08lx\n", GetLastError());
1244 /* The final update should be able to succeed now that a key exists, but
1245 * the previous (invalid) final update prevents it.
1247 SetLastError(0xdeadbeef);
1248 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1249 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
1250 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
1253 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
,
1254 CMSG_DETACHED_FLAG
, CMSG_SIGNED
, &signInfo
, NULL
, NULL
);
1255 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1256 /* Detached CMSG_SIGNED allows non-final updates. */
1257 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
1258 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1259 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1260 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
1261 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1262 /* Now that the private key exists, the final update can succeed (even
1265 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1266 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1267 /* But no updates are allowed after the final update. */
1268 SetLastError(0xdeadbeef);
1269 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
1270 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
1271 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
1272 SetLastError(0xdeadbeef);
1273 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1274 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
1275 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
1278 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1280 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1281 /* Non-detached messages don't allow non-final updates.. */
1282 SetLastError(0xdeadbeef);
1283 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
1284 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
1285 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
1286 /* but they do allow final ones. */
1287 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1288 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
1290 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1292 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1293 /* They also allow final updates with no data. */
1294 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1295 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
1298 CryptDestroyKey(key
);
1299 CryptReleaseContext(signer
.hCryptProv
, 0);
1300 CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
, PROV_RSA_FULL
,
1301 CRYPT_DELETEKEYSET
);
1304 static const BYTE signedEmptyBareContent
[] = {
1305 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1306 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1307 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1308 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1309 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1310 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1311 static const BYTE signedEmptyContent
[] = {
1312 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1313 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1314 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1315 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1316 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1317 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1318 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1319 static const BYTE detachedSignedBareContent
[] = {
1320 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1321 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1322 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1323 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1324 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1325 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1326 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1327 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1328 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1329 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1330 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1331 static const BYTE detachedSignedContent
[] = {
1332 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1333 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1334 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1335 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1336 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1337 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1338 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1339 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1340 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1341 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1342 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1343 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1344 static const BYTE signedBareContent
[] = {
1345 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1346 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1347 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1348 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1349 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1350 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1351 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1352 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1353 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1354 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1355 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1356 static const BYTE signedContent
[] = {
1357 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1358 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1359 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1360 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1361 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1362 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1363 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1364 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1365 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1366 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1367 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1368 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1370 static const BYTE signedHash
[] = {
1371 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1373 static const BYTE signedKeyIdEmptyContent
[] = {
1374 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
1375 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1376 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
1377 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1378 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1379 static const BYTE signedEncodedSigner
[] = {
1380 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1381 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1382 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1383 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1384 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1385 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1386 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1387 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1388 static const BYTE signedWithAuthAttrsBareContent
[] = {
1389 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1390 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1391 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1392 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1393 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1394 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1395 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1396 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1397 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1398 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1399 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1400 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1401 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1402 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1403 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1404 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1405 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1406 0xff,0xc6,0x33,0x63,0x34 };
1407 static BYTE cert
[] = {
1408 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1409 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1410 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1411 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1412 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1413 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1414 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1415 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1416 0xff,0x02,0x01,0x01 };
1417 static BYTE v1CertWithPubKey
[] = {
1418 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1419 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1420 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1421 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1422 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1423 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1424 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1425 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1426 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1427 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1429 static const BYTE signedWithCertEmptyBareContent
[] = {
1430 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1431 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1432 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1433 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1434 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1435 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1436 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1437 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1438 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1439 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1440 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1441 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1442 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1443 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1444 static const BYTE signedWithCertBareContent
[] = {
1445 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1446 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1447 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1448 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1449 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1450 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1451 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1452 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1453 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1454 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1455 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1456 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1457 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1458 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1459 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1460 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1461 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1462 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1463 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1464 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1465 static BYTE crl
[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1466 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1467 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1468 0x30,0x30,0x30,0x30,0x5a };
1469 static const BYTE signedWithCrlEmptyBareContent
[] = {
1470 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1471 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1472 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1473 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1474 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1475 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1476 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1477 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1478 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1479 static const BYTE signedWithCrlBareContent
[] = {
1480 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1481 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1482 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1483 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1484 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1485 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1486 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1487 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1488 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1489 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1490 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1491 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1492 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1493 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1495 static const BYTE signedWithCertAndCrlEmptyBareContent
[] = {
1496 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1497 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1498 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1499 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1500 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1501 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1502 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1503 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1504 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1505 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1506 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1507 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1508 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1509 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1510 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1511 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1512 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1514 static const BYTE signedWithCertAndCrlBareContent
[] = {
1515 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1516 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1517 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1518 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1519 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1520 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1521 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1522 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1523 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1524 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1525 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1526 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1527 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1528 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1529 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1530 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1531 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1532 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1533 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1534 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1535 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1536 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1537 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1538 static const BYTE signedWithCertWithPubKeyBareContent
[] = {
1539 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1540 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1541 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1542 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1543 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1544 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1545 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1546 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1547 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1548 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1549 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1550 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1551 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1552 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1553 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1554 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1555 static BYTE v1CertWithValidPubKey
[] = {
1556 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1557 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1558 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1559 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1560 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1561 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1562 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1563 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1564 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1565 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1566 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1567 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1568 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1569 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1570 static const BYTE signedWithCertWithValidPubKeyEmptyContent
[] = {
1571 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1572 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1573 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1574 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1575 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1576 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1577 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1578 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1579 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1580 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1581 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1582 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1583 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1584 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1585 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1586 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1587 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1588 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1589 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1590 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1591 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1593 static const BYTE signedWithCertWithValidPubKeyContent
[] = {
1594 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1595 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1596 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1597 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1598 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1599 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1600 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1601 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1602 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1603 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1604 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1605 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1606 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1607 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1608 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1609 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1610 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1611 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1612 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1613 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1614 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1615 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1616 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1617 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1618 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1619 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1620 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1622 static void test_signed_msg_encoding(void)
1625 CMSG_SIGNED_ENCODE_INFO signInfo
= { sizeof(signInfo
), 0 };
1626 CMSG_SIGNER_ENCODE_INFO signer
= { sizeof(signer
), 0 };
1627 CERT_INFO certInfo
= { 0 };
1628 CERT_BLOB encodedCert
= { sizeof(cert
), cert
};
1629 CRL_BLOB encodedCrl
= { sizeof(crl
), crl
};
1630 char oid_common_name
[] = szOID_COMMON_NAME
;
1631 CRYPT_ATTR_BLOB commonName
= { sizeof(encodedCommonName
),
1632 encodedCommonName
};
1633 CRYPT_ATTRIBUTE attr
= { oid_common_name
, 1, &commonName
};
1638 certInfo
.SerialNumber
.cbData
= sizeof(serialNum
);
1639 certInfo
.SerialNumber
.pbData
= serialNum
;
1640 certInfo
.Issuer
.cbData
= sizeof(encodedCommonName
);
1641 certInfo
.Issuer
.pbData
= encodedCommonName
;
1642 signer
.pCertInfo
= &certInfo
;
1643 signer
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
1644 signInfo
.cSigners
= 1;
1645 signInfo
.rgSigners
= &signer
;
1647 ret
= CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
,
1648 PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
1649 if (!ret
&& GetLastError() == NTE_EXISTS
) {
1650 ret
= CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
,
1653 ok(ret
, "CryptAcquireContext failed: 0x%lx\n", GetLastError());
1656 skip("No context for tests\n");
1660 ret
= CryptImportKey(signer
.hCryptProv
, privKey
, sizeof(privKey
),
1662 ok(ret
, "CryptImportKey failed: %08lx\n", GetLastError());
1664 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
,
1665 CMSG_DETACHED_FLAG
, CMSG_SIGNED
, &signInfo
, NULL
, NULL
);
1666 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1668 check_param("detached signed empty bare content", msg
,
1669 CMSG_BARE_CONTENT_PARAM
, signedEmptyBareContent
,
1670 sizeof(signedEmptyBareContent
));
1671 check_param("detached signed empty content", msg
, CMSG_CONTENT_PARAM
,
1672 signedEmptyContent
, sizeof(signedEmptyContent
));
1673 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1674 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1675 check_param("detached signed hash", msg
, CMSG_COMPUTED_HASH_PARAM
,
1676 signedHash
, sizeof(signedHash
));
1677 check_param("detached signed bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
1678 detachedSignedBareContent
, sizeof(detachedSignedBareContent
));
1679 check_param("detached signed content", msg
, CMSG_CONTENT_PARAM
,
1680 detachedSignedContent
, sizeof(detachedSignedContent
));
1681 SetLastError(0xdeadbeef);
1682 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 1, NULL
, &size
);
1683 ok(!ret
&& (GetLastError() == CRYPT_E_INVALID_INDEX
||
1684 broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE
/* Win9x */)),
1685 "Expected CRYPT_E_INVALID_INDEX, got %lx\n", GetLastError());
1686 check_param("detached signed encoded signer", msg
, CMSG_ENCODED_SIGNER
,
1687 signedEncodedSigner
, sizeof(signedEncodedSigner
));
1691 certInfo
.SerialNumber
.cbData
= 0;
1692 certInfo
.Issuer
.cbData
= 0;
1693 signer
.SignerId
.dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
1694 U(signer
.SignerId
).KeyId
.cbData
= sizeof(serialNum
);
1695 U(signer
.SignerId
).KeyId
.pbData
= serialNum
;
1696 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1698 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1699 check_param("signed key id empty content", msg
, CMSG_CONTENT_PARAM
,
1700 signedKeyIdEmptyContent
, sizeof(signedKeyIdEmptyContent
));
1703 certInfo
.SerialNumber
.cbData
= sizeof(serialNum
);
1704 certInfo
.SerialNumber
.pbData
= serialNum
;
1705 certInfo
.Issuer
.cbData
= sizeof(encodedCommonName
);
1706 certInfo
.Issuer
.pbData
= encodedCommonName
;
1707 signer
.SignerId
.dwIdChoice
= 0;
1708 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1710 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1712 check_param("signed empty bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
1713 signedEmptyBareContent
, sizeof(signedEmptyBareContent
));
1714 check_param("signed empty content", msg
, CMSG_CONTENT_PARAM
,
1715 signedEmptyContent
, sizeof(signedEmptyContent
));
1716 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1717 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1718 check_param("signed bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
1719 signedBareContent
, sizeof(signedBareContent
));
1720 check_param("signed content", msg
, CMSG_CONTENT_PARAM
,
1721 signedContent
, sizeof(signedContent
));
1725 signer
.cAuthAttr
= 1;
1726 signer
.rgAuthAttr
= &attr
;
1727 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1729 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1731 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1732 check_param("signed with auth attrs bare content", msg
,
1733 CMSG_BARE_CONTENT_PARAM
, signedWithAuthAttrsBareContent
,
1734 sizeof(signedWithAuthAttrsBareContent
));
1738 signer
.cAuthAttr
= 0;
1739 signInfo
.rgCertEncoded
= &encodedCert
;
1740 signInfo
.cCertEncoded
= 1;
1741 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1743 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1745 check_param("signed with cert empty bare content", msg
,
1746 CMSG_BARE_CONTENT_PARAM
, signedWithCertEmptyBareContent
,
1747 sizeof(signedWithCertEmptyBareContent
));
1748 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1749 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1750 check_param("signed with cert bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
1751 signedWithCertBareContent
, sizeof(signedWithCertBareContent
));
1755 signInfo
.cCertEncoded
= 0;
1756 signInfo
.rgCrlEncoded
= &encodedCrl
;
1757 signInfo
.cCrlEncoded
= 1;
1758 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1760 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1762 check_param("signed with crl empty bare content", msg
,
1763 CMSG_BARE_CONTENT_PARAM
, signedWithCrlEmptyBareContent
,
1764 sizeof(signedWithCrlEmptyBareContent
));
1765 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1766 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1767 check_param("signed with crl bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
1768 signedWithCrlBareContent
, sizeof(signedWithCrlBareContent
));
1772 signInfo
.cCertEncoded
= 1;
1773 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1775 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1777 check_param("signed with cert and crl empty bare content", msg
,
1778 CMSG_BARE_CONTENT_PARAM
, signedWithCertAndCrlEmptyBareContent
,
1779 sizeof(signedWithCertAndCrlEmptyBareContent
));
1780 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1781 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
1782 check_param("signed with cert and crl bare content", msg
,
1783 CMSG_BARE_CONTENT_PARAM
, signedWithCertAndCrlBareContent
,
1784 sizeof(signedWithCertAndCrlBareContent
));
1788 /* Test with a cert with a (bogus) public key */
1789 signInfo
.cCrlEncoded
= 0;
1790 encodedCert
.cbData
= sizeof(v1CertWithPubKey
);
1791 encodedCert
.pbData
= v1CertWithPubKey
;
1792 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1794 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1795 check_param("signedWithCertWithPubKeyBareContent", msg
,
1796 CMSG_BARE_CONTENT_PARAM
, signedWithCertWithPubKeyBareContent
,
1797 sizeof(signedWithCertWithPubKeyBareContent
));
1800 encodedCert
.cbData
= sizeof(v1CertWithValidPubKey
);
1801 encodedCert
.pbData
= v1CertWithValidPubKey
;
1802 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1804 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1805 check_param("signedWithCertWithValidPubKeyEmptyContent", msg
,
1806 CMSG_CONTENT_PARAM
, signedWithCertWithValidPubKeyEmptyContent
,
1807 sizeof(signedWithCertWithValidPubKeyEmptyContent
));
1808 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1809 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
1810 check_param("signedWithCertWithValidPubKeyContent", msg
,
1811 CMSG_CONTENT_PARAM
, signedWithCertWithValidPubKeyContent
,
1812 sizeof(signedWithCertWithValidPubKeyContent
));
1815 CryptDestroyKey(key
);
1816 CryptReleaseContext(signer
.hCryptProv
, 0);
1817 CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
, PROV_RSA_FULL
,
1818 CRYPT_DELETEKEYSET
);
1821 static void test_signed_msg_get_param(void)
1825 DWORD size
, value
= 0;
1826 CMSG_SIGNED_ENCODE_INFO signInfo
= { sizeof(signInfo
), 0 };
1827 CMSG_SIGNER_ENCODE_INFO signer
= { sizeof(signer
), 0 };
1828 CERT_INFO certInfo
= { 0 };
1830 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1832 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1834 /* Content and bare content are always gettable */
1836 ret
= CryptMsgGetParam(msg
, CMSG_CONTENT_PARAM
, 0, NULL
, &size
);
1837 ok(ret
|| broken(!ret
/* Win9x */), "CryptMsgGetParam failed: %08lx\n",
1841 skip("message parameters are broken, skipping tests\n");
1845 ret
= CryptMsgGetParam(msg
, CMSG_BARE_CONTENT_PARAM
, 0, NULL
, &size
);
1846 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1847 /* For "signed" messages, so is the version. */
1849 ret
= CryptMsgGetParam(msg
, CMSG_VERSION_PARAM
, 0, NULL
, &size
);
1850 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1851 size
= sizeof(value
);
1852 ret
= CryptMsgGetParam(msg
, CMSG_VERSION_PARAM
, 0, &value
, &size
);
1853 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1854 ok(value
== CMSG_SIGNED_DATA_V1
, "Expected version 1, got %ld\n", value
);
1855 /* But for this message, with no signers, the hash and signer aren't
1859 SetLastError(0xdeadbeef);
1860 ret
= CryptMsgGetParam(msg
, CMSG_ENCODED_SIGNER
, 0, NULL
, &size
);
1861 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_INDEX
,
1862 "Expected CRYPT_E_INVALID_INDEX, got %lx\n", GetLastError());
1863 SetLastError(0xdeadbeef);
1864 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, NULL
, &size
);
1865 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_INDEX
,
1866 "Expected CRYPT_E_INVALID_INDEX, got %lx\n", GetLastError());
1867 /* As usual, the type isn't available. */
1868 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, NULL
, &size
);
1869 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
1870 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
1874 certInfo
.SerialNumber
.cbData
= sizeof(serialNum
);
1875 certInfo
.SerialNumber
.pbData
= serialNum
;
1876 certInfo
.Issuer
.cbData
= sizeof(encodedCommonName
);
1877 certInfo
.Issuer
.pbData
= encodedCommonName
;
1878 signer
.pCertInfo
= &certInfo
;
1879 signer
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
1880 signInfo
.cSigners
= 1;
1881 signInfo
.rgSigners
= &signer
;
1883 ret
= CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
,
1884 PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
1885 if (!ret
&& GetLastError() == NTE_EXISTS
) {
1886 ret
= CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
,
1889 ok(ret
, "CryptAcquireContext failed: 0x%lx\n", GetLastError());
1892 skip("No context for tests\n");
1896 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1898 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1900 /* This message, with one signer, has the hash and signer for index 0
1901 * available, but not for other indexes.
1904 ret
= CryptMsgGetParam(msg
, CMSG_ENCODED_SIGNER
, 0, NULL
, &size
);
1905 ok(ret
, "CryptMsgGetParam failed: %lx\n", GetLastError());
1906 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, NULL
, &size
);
1907 ok(ret
, "CryptMsgGetParam failed: %lx\n", GetLastError());
1909 SetLastError(0xdeadbeef);
1910 ret
= CryptMsgGetParam(msg
, CMSG_ENCODED_SIGNER
, 1, NULL
, &size
);
1911 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_INDEX
,
1912 "Expected CRYPT_E_INVALID_INDEX, got %lx\n", GetLastError());
1913 SetLastError(0xdeadbeef);
1914 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 1, NULL
, &size
);
1915 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_INDEX
,
1916 "Expected CRYPT_E_INVALID_INDEX, got %lx\n", GetLastError());
1917 /* As usual, the type isn't available. */
1918 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, NULL
, &size
);
1919 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
1920 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
1924 /* Opening the message using the CMS fields.. */
1925 certInfo
.SerialNumber
.cbData
= 0;
1926 certInfo
.Issuer
.cbData
= 0;
1927 signer
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
1928 U(signer
.SignerId
).IssuerSerialNumber
.Issuer
.cbData
=
1929 sizeof(encodedCommonName
);
1930 U(signer
.SignerId
).IssuerSerialNumber
.Issuer
.pbData
= encodedCommonName
;
1931 U(signer
.SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
=
1933 U(signer
.SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
= serialNum
;
1934 ret
= CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
,
1935 PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
1936 if (!ret
&& GetLastError() == NTE_EXISTS
)
1937 ret
= CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
,
1939 ok(ret
, "CryptAcquireContextA failed: %lx\n", GetLastError());
1940 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
,
1941 CMSG_CRYPT_RELEASE_CONTEXT_FLAG
, CMSG_SIGNED
, &signInfo
, NULL
, NULL
);
1942 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1943 /* still results in the version being 1 when the issuer and serial number
1944 * are used and no additional CMS fields are used.
1946 size
= sizeof(value
);
1947 ret
= CryptMsgGetParam(msg
, CMSG_VERSION_PARAM
, 0, &value
, &size
);
1948 ok(ret
|| broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE
),
1949 "CryptMsgGetParam failed: %08lx\n", GetLastError());
1951 ok(value
== CMSG_SIGNED_DATA_V1
, "expected version 1, got %ld\n", value
);
1952 /* Apparently the encoded signer can be retrieved.. */
1953 ret
= CryptMsgGetParam(msg
, CMSG_ENCODED_SIGNER
, 0, NULL
, &size
);
1954 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1955 /* but the signer info, CMS signer info, and cert ID can't be. */
1956 SetLastError(0xdeadbeef);
1957 ret
= CryptMsgGetParam(msg
, CMSG_SIGNER_INFO_PARAM
, 0, NULL
, &size
);
1958 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
1959 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
1960 SetLastError(0xdeadbeef);
1961 ret
= CryptMsgGetParam(msg
, CMSG_CMS_SIGNER_INFO_PARAM
, 0, NULL
, &size
);
1962 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
1963 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
1964 SetLastError(0xdeadbeef);
1965 ret
= CryptMsgGetParam(msg
, CMSG_SIGNER_CERT_ID_PARAM
, 0, NULL
, &size
);
1966 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
1967 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
1970 /* Using the KeyId field of the SignerId results in the version becoming
1973 signer
.SignerId
.dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
1974 U(signer
.SignerId
).KeyId
.cbData
= sizeof(serialNum
);
1975 U(signer
.SignerId
).KeyId
.pbData
= serialNum
;
1976 ret
= CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
,
1977 PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
1978 if (!ret
&& GetLastError() == NTE_EXISTS
)
1979 ret
= CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, NULL
,
1981 ok(ret
, "CryptAcquireContextA failed: %lx\n", GetLastError());
1982 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
,
1983 CMSG_CRYPT_RELEASE_CONTEXT_FLAG
, CMSG_SIGNED
, &signInfo
, NULL
, NULL
);
1984 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1985 size
= sizeof(value
);
1986 ret
= CryptMsgGetParam(msg
, CMSG_VERSION_PARAM
, 0, &value
, &size
);
1987 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1989 ok(value
== CMSG_SIGNED_DATA_V3
, "expected version 3, got %ld\n", value
);
1990 /* Even for a CMS message, the signer can be retrieved.. */
1991 ret
= CryptMsgGetParam(msg
, CMSG_ENCODED_SIGNER
, 0, NULL
, &size
);
1992 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1993 /* but the signer info, CMS signer info, and cert ID can't be. */
1994 SetLastError(0xdeadbeef);
1995 ret
= CryptMsgGetParam(msg
, CMSG_SIGNER_INFO_PARAM
, 0, NULL
, &size
);
1996 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
1997 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
1998 SetLastError(0xdeadbeef);
1999 ret
= CryptMsgGetParam(msg
, CMSG_CMS_SIGNER_INFO_PARAM
, 0, NULL
, &size
);
2000 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
2001 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
2002 SetLastError(0xdeadbeef);
2003 ret
= CryptMsgGetParam(msg
, CMSG_SIGNER_CERT_ID_PARAM
, 0, NULL
, &size
);
2004 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
2005 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
2008 CryptReleaseContext(signer
.hCryptProv
, 0);
2009 CryptAcquireContextA(&signer
.hCryptProv
, cspNameA
, MS_DEF_PROV_A
,
2010 PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
2013 static void test_signed_msg(void)
2015 test_signed_msg_open();
2016 test_signed_msg_update();
2017 test_signed_msg_encoding();
2018 test_signed_msg_get_param();
2021 static char oid_rsa_rc4
[] = szOID_RSA_RC4
;
2023 static void test_enveloped_msg_open(void)
2027 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo
= { 0 };
2028 PCCERT_CONTEXT context
;
2030 SetLastError(0xdeadbeef);
2031 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
,
2032 &envelopedInfo
, NULL
, NULL
);
2033 ok(!msg
&& GetLastError() == E_INVALIDARG
,
2034 "expected E_INVALIDARG, got %08lx\n", GetLastError());
2036 envelopedInfo
.cbSize
= sizeof(envelopedInfo
);
2037 SetLastError(0xdeadbeef);
2038 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
,
2039 &envelopedInfo
, NULL
, NULL
);
2041 (GetLastError() == CRYPT_E_UNKNOWN_ALGO
||
2042 GetLastError() == E_INVALIDARG
), /* Win9x */
2043 "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08lx\n", GetLastError());
2045 envelopedInfo
.ContentEncryptionAlgorithm
.pszObjId
= oid_rsa_rc4
;
2046 SetLastError(0xdeadbeef);
2047 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
,
2048 &envelopedInfo
, NULL
, NULL
);
2050 broken(!msg
), /* Win9x */
2051 "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2054 envelopedInfo
.cRecipients
= 1;
2057 SetLastError(0xdeadbeef);
2058 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
,
2059 &envelopedInfo
, NULL
, NULL
);
2060 ok(!msg
&& GetLastError() == E_INVALIDARG
,
2061 "expected E_INVALIDARG, got %08lx\n", GetLastError());
2064 context
= CertCreateCertificateContext(X509_ASN_ENCODING
,
2065 v1CertWithValidPubKey
, sizeof(v1CertWithValidPubKey
));
2068 envelopedInfo
.rgpRecipientCert
= (PCERT_INFO
*)&context
->pCertInfo
;
2069 SetLastError(0xdeadbeef);
2070 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
,
2071 &envelopedInfo
, NULL
, NULL
);
2072 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2074 SetLastError(0xdeadbeef);
2075 ret
= CryptAcquireContextA(&envelopedInfo
.hCryptProv
, NULL
, NULL
,
2076 PROV_RSA_FULL
, CRYPT_VERIFYCONTEXT
);
2077 ok(ret
, "CryptAcquireContextA failed: %08lx\n", GetLastError());
2078 SetLastError(0xdeadbeef);
2079 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
,
2080 &envelopedInfo
, NULL
, NULL
);
2081 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2083 CryptReleaseContext(envelopedInfo
.hCryptProv
, 0);
2084 CertFreeCertificateContext(context
);
2087 win_skip("failed to create certificate context, skipping tests\n");
2090 static void test_enveloped_msg_update(void)
2094 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo
= { sizeof(envelopedInfo
), 0,
2095 { oid_rsa_rc4
, { 0, NULL
} }, NULL
};
2096 CMSG_STREAM_INFO streamInfo
= { 0, nop_stream_output
, NULL
};
2098 SetLastError(0xdeadbeef);
2099 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
,
2100 &envelopedInfo
, NULL
, NULL
);
2102 broken(!msg
), /* Win9x */
2103 "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2106 SetLastError(0xdeadbeef);
2107 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
2108 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
2109 "expected CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
2110 SetLastError(0xdeadbeef);
2111 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
2112 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2113 SetLastError(0xdeadbeef);
2114 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
2115 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
2116 "expected CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
2119 SetLastError(0xdeadbeef);
2120 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
,
2121 &envelopedInfo
, NULL
, NULL
);
2123 broken(!msg
), /* Win9x */
2124 "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2127 SetLastError(0xdeadbeef);
2128 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
2129 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
2130 "expected CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
2131 SetLastError(0xdeadbeef);
2132 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
2134 broken(!ret
&& GetLastError() == NTE_PERM
), /* some NT4 */
2135 "CryptMsgUpdate failed: %08lx\n", GetLastError());
2136 SetLastError(0xdeadbeef);
2137 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
2138 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
2139 "expected CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
2142 SetLastError(0xdeadbeef);
2143 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
2144 CMSG_ENVELOPED
, &envelopedInfo
, NULL
, NULL
);
2146 broken(!msg
), /* Win9x */
2147 "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2150 SetLastError(0xdeadbeef);
2151 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
2152 ok(!ret
&& GetLastError() == E_INVALIDARG
,
2153 "expected E_INVALIDARG, got %08lx\n", GetLastError());
2154 SetLastError(0xdeadbeef);
2155 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
2156 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2159 SetLastError(0xdeadbeef);
2160 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
2161 CMSG_ENVELOPED
, &envelopedInfo
, NULL
, NULL
);
2163 broken(!msg
), /* Win9x */
2164 "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2167 SetLastError(0xdeadbeef);
2168 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
2169 ok(!ret
&& GetLastError() == E_INVALIDARG
,
2170 "expected E_INVALIDARG, got %08lx\n", GetLastError());
2171 SetLastError(0xdeadbeef);
2172 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
2174 broken(!ret
&& GetLastError() == NTE_PERM
), /* some NT4 */
2175 "CryptMsgUpdate failed: %08lx\n", GetLastError());
2178 SetLastError(0xdeadbeef);
2179 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
,
2180 &envelopedInfo
, NULL
, &streamInfo
);
2182 broken(!msg
), /* Win9x */
2183 "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2186 SetLastError(0xdeadbeef);
2187 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
2188 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2189 SetLastError(0xdeadbeef);
2190 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
2191 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2194 SetLastError(0xdeadbeef);
2195 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
,
2196 &envelopedInfo
, NULL
, &streamInfo
);
2198 broken(!msg
), /* Win9x */
2199 "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2202 SetLastError(0xdeadbeef);
2203 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
2204 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2205 SetLastError(0xdeadbeef);
2206 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
2208 broken(!ret
&& GetLastError() == NTE_PERM
), /* some NT4 */
2209 "CryptMsgUpdate failed: %08lx\n", GetLastError());
2214 static const BYTE envelopedEmptyBareContent
[] = {
2215 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2216 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2217 0x03,0x04,0x05,0x00,0x80,0x00 };
2218 static const BYTE envelopedEmptyContent
[] = {
2219 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24,
2220 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2221 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2222 0x03,0x04,0x05,0x00,0x80,0x00 };
2224 static void test_enveloped_msg_encoding(void)
2227 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo
= { sizeof(envelopedInfo
), 0,
2228 { oid_rsa_rc4
, { 0, NULL
} }, NULL
};
2230 SetLastError(0xdeadbeef);
2231 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
,
2232 &envelopedInfo
, NULL
, NULL
);
2234 broken(!msg
), /* Win9x */
2235 "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2238 check_param("enveloped empty bare content", msg
,
2239 CMSG_BARE_CONTENT_PARAM
, envelopedEmptyBareContent
,
2240 sizeof(envelopedEmptyBareContent
));
2241 check_param("enveloped empty content", msg
, CMSG_CONTENT_PARAM
,
2242 envelopedEmptyContent
, sizeof(envelopedEmptyContent
));
2247 static void test_enveloped_msg(void)
2249 test_enveloped_msg_open();
2250 test_enveloped_msg_update();
2251 test_enveloped_msg_encoding();
2254 static CRYPT_DATA_BLOB b4
= { 0, NULL
};
2255 static const struct update_accum a4
= { 1, &b4
};
2257 static const BYTE bogusOIDContent
[] = {
2258 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2260 static const BYTE bogusHashContent
[] = {
2261 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2262 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2263 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2264 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2265 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2266 static const BYTE envelopedBareContentWithoutData
[] = {
2267 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2268 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2269 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2270 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2271 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b,
2272 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f,
2273 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94,
2274 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72,
2275 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18,
2276 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3,
2277 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6,
2278 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49,
2279 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e,
2280 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2281 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 };
2283 static void test_decode_msg_update(void)
2287 CMSG_STREAM_INFO streamInfo
= { 0 };
2289 struct update_accum accum
= { 0, NULL
};
2291 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2292 /* Update with a full message in a final update */
2293 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
), TRUE
);
2294 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
2295 /* Can't update after a final update */
2296 SetLastError(0xdeadbeef);
2297 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
), TRUE
);
2298 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
2299 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
2302 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2303 /* Can't send a non-final update without streaming */
2304 SetLastError(0xdeadbeef);
2305 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
),
2307 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
2308 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
2309 /* A subsequent final update succeeds */
2310 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
), TRUE
);
2311 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
2316 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, &streamInfo
);
2317 /* Updating a message that has a NULL stream callback fails */
2318 SetLastError(0xdeadbeef);
2319 /* Crashes on some Win9x */
2320 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
),
2323 ok(!ret
&& (GetLastError() == STATUS_ACCESS_VIOLATION
||
2324 GetLastError() == STATUS_ILLEGAL_INSTRUCTION
/* WinME */),
2325 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %lx\n",
2327 /* Changing the callback pointer after the fact yields the same error (so
2328 * the message must copy the stream info, not just store a pointer to it)
2330 streamInfo
.pfnStreamOutput
= nop_stream_output
;
2331 SetLastError(0xdeadbeef);
2332 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
),
2335 ok(!ret
&& (GetLastError() == STATUS_ACCESS_VIOLATION
||
2336 GetLastError() == STATUS_ILLEGAL_INSTRUCTION
/* WinME */),
2337 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %lx\n",
2342 /* Empty non-final updates are allowed when streaming.. */
2343 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, &streamInfo
);
2344 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
2345 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
2346 /* but final updates aren't when not enough data has been received. */
2347 SetLastError(0xdeadbeef);
2348 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
2350 ok(!ret
&& GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA
,
2351 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %lx\n", GetLastError());
2354 /* Updating the message byte by byte is legal */
2355 streamInfo
.pfnStreamOutput
= accumulating_stream_output
;
2356 streamInfo
.pvArg
= &accum
;
2357 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, &streamInfo
);
2358 for (i
= 0, ret
= TRUE
; ret
&& i
< sizeof(dataEmptyContent
); i
++)
2359 ret
= CryptMsgUpdate(msg
, &dataEmptyContent
[i
], 1, FALSE
);
2360 ok(ret
, "CryptMsgUpdate failed on byte %ld: %lx\n", i
, GetLastError());
2361 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
2362 ok(ret
, "CryptMsgUpdate failed on byte %ld: %lx\n", i
, GetLastError());
2365 check_updates("byte-by-byte empty content", &a4
, &accum
);
2366 free_updates(&accum
);
2368 /* Decoding bogus content fails in non-streaming mode.. */
2369 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2370 SetLastError(0xdeadbeef);
2371 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
2372 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
2373 GetLastError() == OSS_PDU_MISMATCH
/* Win9x */),
2374 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %lx\n",
2377 /* and as the final update in streaming mode.. */
2378 streamInfo
.pfnStreamOutput
= nop_stream_output
;
2379 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, &streamInfo
);
2380 SetLastError(0xdeadbeef);
2381 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
2382 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
2383 GetLastError() == OSS_PDU_MISMATCH
/* Win9x */),
2384 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %lx\n",
2387 /* and even as a non-final update in streaming mode. */
2388 streamInfo
.pfnStreamOutput
= nop_stream_output
;
2389 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, &streamInfo
);
2390 SetLastError(0xdeadbeef);
2391 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
2393 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
2394 GetLastError() == OSS_PDU_MISMATCH
/* Win9x */),
2395 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %lx\n",
2399 /* An empty message can be opened with undetermined type.. */
2400 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2401 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
),
2403 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
2405 /* but decoding it as an explicitly typed message fails. */
2406 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, 0, NULL
,
2408 SetLastError(0xdeadbeef);
2409 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
),
2411 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
2412 GetLastError() == OSS_PDU_MISMATCH
/* Win9x */),
2413 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %lx\n",
2416 /* On the other hand, decoding the bare content of an empty message fails
2417 * with unspecified type..
2419 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2420 SetLastError(0xdeadbeef);
2421 ret
= CryptMsgUpdate(msg
, dataEmptyBareContent
,
2422 sizeof(dataEmptyBareContent
), TRUE
);
2423 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
2424 GetLastError() == OSS_PDU_MISMATCH
/* Win9x */),
2425 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %lx\n",
2428 /* but succeeds with explicit type. */
2429 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, 0, NULL
,
2431 ret
= CryptMsgUpdate(msg
, dataEmptyBareContent
,
2432 sizeof(dataEmptyBareContent
), TRUE
);
2433 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
2436 /* Decoding valid content with an unsupported OID fails */
2437 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2438 SetLastError(0xdeadbeef);
2439 ret
= CryptMsgUpdate(msg
, bogusOIDContent
, sizeof(bogusOIDContent
), TRUE
);
2440 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
2441 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
2444 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2445 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2446 SetLastError(0xdeadbeef);
2447 ret
= CryptMsgUpdate(msg
, hashEmptyContent
, sizeof(hashEmptyContent
), TRUE
);
2448 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2449 "CryptMsgUpdate failed: %08lx\n", GetLastError());
2451 /* while with specified type it fails. */
2452 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
2454 SetLastError(0xdeadbeef);
2455 ret
= CryptMsgUpdate(msg
, hashEmptyContent
, sizeof(hashEmptyContent
), TRUE
);
2456 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
2457 GetLastError() == OSS_PDU_MISMATCH
/* some Win9x */ ||
2458 GetLastError() == OSS_DATA_ERROR
/* some Win9x */),
2459 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %lx\n",
2462 /* On the other hand, decoding the bare content of an empty hash message
2463 * fails with unspecified type..
2465 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2466 SetLastError(0xdeadbeef);
2467 ret
= CryptMsgUpdate(msg
, hashEmptyBareContent
,
2468 sizeof(hashEmptyBareContent
), TRUE
);
2469 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
2470 GetLastError() == OSS_PDU_MISMATCH
/* some Win9x */ ||
2471 GetLastError() == OSS_DATA_ERROR
/* some Win9x */),
2472 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %lx\n",
2475 /* but succeeds with explicit type. */
2476 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
2478 ret
= CryptMsgUpdate(msg
, hashEmptyBareContent
,
2479 sizeof(hashEmptyBareContent
), TRUE
);
2480 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* win9x */),
2481 "CryptMsgUpdate failed: %lx\n", GetLastError());
2484 /* And again, opening a (non-empty) hash message with unspecified type
2487 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2488 SetLastError(0xdeadbeef);
2489 ret
= CryptMsgUpdate(msg
, hashContent
, sizeof(hashContent
), TRUE
);
2490 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2492 /* while with specified type it fails.. */
2493 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
2495 SetLastError(0xdeadbeef);
2496 ret
= CryptMsgUpdate(msg
, hashContent
, sizeof(hashContent
), TRUE
);
2497 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
2498 GetLastError() == OSS_PDU_MISMATCH
/* some Win9x */ ||
2499 GetLastError() == OSS_DATA_ERROR
/* some Win9x */),
2500 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %lx\n",
2503 /* and decoding the bare content of a non-empty hash message fails with
2504 * unspecified type..
2506 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2507 SetLastError(0xdeadbeef);
2508 ret
= CryptMsgUpdate(msg
, hashBareContent
, sizeof(hashBareContent
), TRUE
);
2509 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
2510 GetLastError() == OSS_PDU_MISMATCH
/* some Win9x */ ||
2511 GetLastError() == OSS_DATA_ERROR
/* some Win9x */),
2512 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %lx\n",
2515 /* but succeeds with explicit type. */
2516 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
2518 ret
= CryptMsgUpdate(msg
, hashBareContent
, sizeof(hashBareContent
), TRUE
);
2519 ok(ret
, "CryptMsgUpdate failed: %lx\n", GetLastError());
2522 /* Opening a (non-empty) hash message with unspecified type and a bogus
2523 * hash value succeeds..
2525 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2526 SetLastError(0xdeadbeef);
2527 ret
= CryptMsgUpdate(msg
, bogusHashContent
, sizeof(bogusHashContent
), TRUE
);
2528 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2531 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2532 ret
= CryptMsgUpdate(msg
, signedContent
, sizeof(signedContent
), TRUE
);
2533 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2535 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2536 SetLastError(0xdeadbeef);
2537 ret
= CryptMsgUpdate(msg
, signedWithCertAndCrlBareContent
,
2538 sizeof(signedWithCertAndCrlBareContent
), TRUE
);
2539 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
2540 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2541 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08lx\n",
2544 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, 0, NULL
,
2546 ret
= CryptMsgUpdate(msg
, signedWithCertAndCrlBareContent
,
2547 sizeof(signedWithCertAndCrlBareContent
), TRUE
);
2548 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2551 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
, 0, 0,
2553 /* The first update succeeds.. */
2554 ret
= CryptMsgUpdate(msg
, detachedSignedContent
,
2555 sizeof(detachedSignedContent
), TRUE
);
2556 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2557 /* as does a second (probably to update the detached portion).. */
2558 ret
= CryptMsgUpdate(msg
, detachedSignedContent
,
2559 sizeof(detachedSignedContent
), TRUE
);
2560 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2561 /* while a third fails. */
2562 ret
= CryptMsgUpdate(msg
, detachedSignedContent
,
2563 sizeof(detachedSignedContent
), TRUE
);
2564 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
2565 "expected CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
2568 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
, 0, 0, NULL
, &streamInfo
);
2569 ret
= CryptMsgUpdate(msg
, detachedSignedContent
, sizeof(detachedSignedContent
), FALSE
);
2570 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2571 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
2572 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2573 ret
= CryptMsgUpdate(msg
, detachedSignedContent
, sizeof(detachedSignedContent
), FALSE
);
2574 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2575 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
2576 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2578 ret
= CryptMsgUpdate(msg
, detachedSignedContent
, sizeof(detachedSignedContent
), TRUE
);
2579 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
2580 "expected CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
2583 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
, 0, NULL
,
2585 SetLastError(0xdeadbeef);
2586 ret
= CryptMsgUpdate(msg
, envelopedEmptyBareContent
,
2587 sizeof(envelopedEmptyBareContent
), TRUE
);
2588 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2591 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
, 0, NULL
,
2593 SetLastError(0xdeadbeef);
2594 ret
= CryptMsgUpdate(msg
, envelopedEmptyContent
,
2595 sizeof(envelopedEmptyContent
), TRUE
);
2597 (GetLastError() == CRYPT_E_ASN1_BADTAG
||
2598 GetLastError() == OSS_DATA_ERROR
), /* Win9x */
2599 "expected CRYPT_E_ASN1_BADTAG, got %08lx\n", GetLastError());
2602 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2603 SetLastError(0xdeadbeef);
2604 ret
= CryptMsgUpdate(msg
, envelopedEmptyBareContent
,
2605 sizeof(envelopedEmptyBareContent
), TRUE
);
2607 (GetLastError() == CRYPT_E_ASN1_BADTAG
||
2608 GetLastError() == OSS_DATA_ERROR
), /* Win9x */
2609 "expected CRYPT_E_ASN1_BADTAG, got %08lx\n", GetLastError());
2612 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2613 SetLastError(0xdeadbeef);
2614 ret
= CryptMsgUpdate(msg
, envelopedEmptyContent
,
2615 sizeof(envelopedEmptyContent
), TRUE
);
2616 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2619 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
, 0, NULL
,
2621 SetLastError(0xdeadbeef);
2622 ret
= CryptMsgUpdate(msg
, envelopedBareContentWithoutData
,
2623 sizeof(envelopedBareContentWithoutData
), TRUE
);
2624 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2628 static const BYTE hashParam
[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2629 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2631 static void compare_signer_info(const CMSG_SIGNER_INFO
*got
,
2632 const CMSG_SIGNER_INFO
*expected
)
2634 ok(got
->dwVersion
== expected
->dwVersion
, "Expected version %ld, got %ld\n",
2635 expected
->dwVersion
, got
->dwVersion
);
2636 ok(got
->Issuer
.cbData
== expected
->Issuer
.cbData
,
2637 "Expected issuer size %ld, got %ld\n", expected
->Issuer
.cbData
,
2638 got
->Issuer
.cbData
);
2639 ok(!memcmp(got
->Issuer
.pbData
, expected
->Issuer
.pbData
, got
->Issuer
.cbData
),
2640 "Unexpected issuer\n");
2641 ok(got
->SerialNumber
.cbData
== expected
->SerialNumber
.cbData
,
2642 "Expected serial number size %ld, got %ld\n", expected
->SerialNumber
.cbData
,
2643 got
->SerialNumber
.cbData
);
2644 ok(!memcmp(got
->SerialNumber
.pbData
, expected
->SerialNumber
.pbData
,
2645 got
->SerialNumber
.cbData
), "Unexpected serial number\n");
2646 /* FIXME: check more things */
2649 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO
*got
,
2650 const CMSG_CMS_SIGNER_INFO
*expected
)
2652 ok(got
->dwVersion
== expected
->dwVersion
, "Expected version %ld, got %ld\n",
2653 expected
->dwVersion
, got
->dwVersion
);
2654 ok(got
->SignerId
.dwIdChoice
== expected
->SignerId
.dwIdChoice
,
2655 "Expected id choice %ld, got %ld\n", expected
->SignerId
.dwIdChoice
,
2656 got
->SignerId
.dwIdChoice
);
2657 if (got
->SignerId
.dwIdChoice
== expected
->SignerId
.dwIdChoice
)
2659 if (got
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
)
2661 ok(U(got
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
2662 U(expected
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
,
2663 "Expected issuer size %ld, got %ld\n",
2664 U(expected
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
,
2665 U(got
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
2666 ok(!memcmp(U(got
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
2667 U(expected
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
2668 U(got
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
2669 "Unexpected issuer\n");
2670 ok(U(got
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
2671 U(expected
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
,
2672 "Expected serial number size %ld, got %ld\n",
2673 U(expected
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
,
2674 U(got
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
2675 ok(!memcmp(U(got
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
2676 U(expected
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
2677 U(got
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
),
2678 "Unexpected serial number\n");
2682 ok(U(got
->SignerId
).KeyId
.cbData
== U(expected
->SignerId
).KeyId
.cbData
,
2683 "expected key id size %ld, got %ld\n",
2684 U(expected
->SignerId
).KeyId
.cbData
, U(got
->SignerId
).KeyId
.cbData
);
2685 ok(!memcmp(U(expected
->SignerId
).KeyId
.pbData
,
2686 U(got
->SignerId
).KeyId
.pbData
, U(got
->SignerId
).KeyId
.cbData
),
2687 "unexpected key id\n");
2690 /* FIXME: check more things */
2693 static const BYTE signedWithCertAndCrlComputedHash
[] = {
2694 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2696 static BYTE keyIdIssuer
[] = {
2697 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2698 0x0a,0x07,0x01,0x04,0x01,0x01 };
2699 static const BYTE publicPrivateKeyPair
[] = {
2700 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00,
2701 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b,
2702 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50,
2703 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54,
2704 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39,
2705 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7,
2706 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48,
2707 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17,
2708 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54,
2709 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33,
2710 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52,
2711 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e,
2712 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61,
2713 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb,
2714 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02,
2715 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90,
2716 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e,
2717 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce,
2718 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14,
2719 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5,
2720 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5,
2721 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94,
2722 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68,
2723 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71,
2724 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25,
2725 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc,
2726 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a,
2727 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64,
2728 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77,
2729 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68,
2730 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab,
2731 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9,
2732 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed,
2733 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01,
2734 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e,
2735 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71,
2736 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0,
2737 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87,
2738 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b,
2739 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e };
2740 static const BYTE envelopedMessage
[] = {
2741 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,
2742 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,
2743 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,
2744 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,
2745 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
2746 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65,
2747 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae,
2748 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1,
2749 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51,
2750 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf,
2751 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b,
2752 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e,
2753 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e,
2754 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70,
2755 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,
2756 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,
2757 0x04,0x5f,0x80,0xf2,0x17 };
2758 static const BYTE envelopedBareMessage
[] = {
2759 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2760 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2761 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2762 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2763 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d,
2764 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d,
2765 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5,
2766 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e,
2767 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2,
2768 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4,
2769 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70,
2770 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c,
2771 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55,
2772 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2773 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c,
2775 static const BYTE envelopedMessageWith3Recps
[] = {
2776 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,
2777 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e,
2778 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,
2779 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,
2780 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,
2781 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e,
2782 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba,
2783 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f,
2784 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5,
2785 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21,
2786 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae,
2787 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0,
2788 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96,
2789 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae,
2790 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,
2791 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,
2792 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6,
2793 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
2794 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf,
2795 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9,
2796 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3,
2797 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02,
2798 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70,
2799 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3,
2800 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74,
2801 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94,
2802 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7,
2803 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,
2804 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,
2805 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
2806 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98,
2807 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5,
2808 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9,
2809 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3,
2810 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8,
2811 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac,
2812 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc,
2813 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5,
2814 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1,
2815 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
2816 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,
2817 0x80,0x04,0x4e,0x99,0x9d,0x4c };
2818 static const BYTE serialNumber
[] = {
2819 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2,
2821 static const BYTE issuer
[] = {
2822 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 };
2824 static void test_decode_msg_get_param(void)
2827 HCRYPTPROV hCryptProv
;
2830 DWORD size
= 0, value
, req_size
;
2832 CMSG_CTRL_DECRYPT_PARA decryptPara
= { sizeof(decryptPara
), 0 };
2834 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2835 SetLastError(0xdeadbeef);
2836 ret
= CryptMsgGetParam(msg
, CMSG_CONTENT_PARAM
, 0, NULL
, &size
);
2837 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
2838 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
2839 ret
= CryptMsgUpdate(msg
, dataContent
, sizeof(dataContent
), TRUE
);
2840 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2841 check_param("data content", msg
, CMSG_CONTENT_PARAM
, msgData
,
2845 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2846 ret
= CryptMsgUpdate(msg
, hashEmptyContent
, sizeof(hashEmptyContent
), TRUE
);
2849 /* Crashes on some Win9x */
2850 check_param("empty hash content", msg
, CMSG_CONTENT_PARAM
, NULL
, 0);
2851 check_param("empty hash hash data", msg
, CMSG_HASH_DATA_PARAM
, NULL
, 0);
2852 check_param("empty hash computed hash", msg
, CMSG_COMPUTED_HASH_PARAM
,
2853 emptyHashParam
, sizeof(emptyHashParam
));
2856 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2857 ret
= CryptMsgUpdate(msg
, hashContent
, sizeof(hashContent
), TRUE
);
2858 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2859 check_param("hash content", msg
, CMSG_CONTENT_PARAM
, msgData
,
2861 check_param("hash hash data", msg
, CMSG_HASH_DATA_PARAM
, hashParam
,
2863 check_param("hash computed hash", msg
, CMSG_COMPUTED_HASH_PARAM
,
2864 hashParam
, sizeof(hashParam
));
2865 /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2866 * even though there's only one hash.
2868 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 1, NULL
, &size
);
2869 ok(ret
|| GetLastError() == OSS_DATA_ERROR
/* Win9x */,
2870 "CryptMsgGetParam failed: %08lx\n", GetLastError());
2872 buf
= CryptMemAlloc(size
);
2877 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 1, buf
, &size
);
2878 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2879 ok(size
== sizeof(hashParam
), "Unexpected size %ld\n", size
);
2880 ok(!memcmp(buf
, hashParam
, size
), "Unexpected value\n");
2883 check_param("hash inner OID", msg
, CMSG_INNER_CONTENT_TYPE_PARAM
,
2884 (const BYTE
*)szOID_RSA_data
, strlen(szOID_RSA_data
) + 1);
2885 value
= CMSG_HASHED_DATA_V0
;
2886 check_param("hash version", msg
, CMSG_VERSION_PARAM
, (const BYTE
*)&value
,
2890 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2891 ret
= CryptMsgUpdate(msg
, signedContent
, sizeof(signedContent
), TRUE
);
2892 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2893 check_param("signed content", msg
, CMSG_CONTENT_PARAM
, msgData
,
2895 check_param("inner content", msg
, CMSG_INNER_CONTENT_TYPE_PARAM
,
2896 (const BYTE
*)szOID_RSA_data
, strlen(szOID_RSA_data
) + 1);
2897 size
= sizeof(value
);
2899 ret
= CryptMsgGetParam(msg
, CMSG_SIGNER_COUNT_PARAM
, 0, &value
, &size
);
2900 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2901 ok(value
== 1, "Expected 1 signer, got %ld\n", value
);
2903 ret
= CryptMsgGetParam(msg
, CMSG_SIGNER_INFO_PARAM
, 0, NULL
, &size
);
2904 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2905 "CryptMsgGetParam failed: %08lx\n", GetLastError());
2907 buf
= CryptMemAlloc(size
);
2912 CMSG_SIGNER_INFO signer
= { 0 };
2914 signer
.dwVersion
= 1;
2915 signer
.Issuer
.cbData
= sizeof(encodedCommonName
);
2916 signer
.Issuer
.pbData
= encodedCommonName
;
2917 signer
.SerialNumber
.cbData
= sizeof(serialNum
);
2918 signer
.SerialNumber
.pbData
= serialNum
;
2919 signer
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
2922 CryptMsgGetParam(msg
, CMSG_SIGNER_INFO_PARAM
, 0, buf
, &size
);
2923 ok(size
== req_size
, "size = %lu, expected %lu\n", size
, req_size
);
2924 compare_signer_info((CMSG_SIGNER_INFO
*)buf
, &signer
);
2927 /* Getting the CMS signer info of a PKCS7 message is possible. */
2929 ret
= CryptMsgGetParam(msg
, CMSG_CMS_SIGNER_INFO_PARAM
, 0, NULL
, &size
);
2930 ok(ret
|| broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE
/* Win9x */),
2931 "CryptMsgGetParam failed: %08lx\n", GetLastError());
2933 buf
= CryptMemAlloc(size
);
2938 CMSG_CMS_SIGNER_INFO signer
= { 0 };
2940 signer
.dwVersion
= 1;
2941 signer
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
2942 U(signer
.SignerId
).IssuerSerialNumber
.Issuer
.cbData
=
2943 sizeof(encodedCommonName
);
2944 U(signer
.SignerId
).IssuerSerialNumber
.Issuer
.pbData
= encodedCommonName
;
2945 U(signer
.SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
=
2947 U(signer
.SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
= serialNum
;
2948 signer
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
2949 CryptMsgGetParam(msg
, CMSG_CMS_SIGNER_INFO_PARAM
, 0, buf
, &size
);
2950 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO
*)buf
, &signer
);
2953 /* index is ignored when getting signer count */
2954 size
= sizeof(value
);
2955 ret
= CryptMsgGetParam(msg
, CMSG_SIGNER_COUNT_PARAM
, 1, &value
, &size
);
2956 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2957 ok(value
== 1, "Expected 1 signer, got %ld\n", value
);
2958 ret
= CryptMsgGetParam(msg
, CMSG_CERT_COUNT_PARAM
, 0, &value
, &size
);
2959 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2960 ok(value
== 0, "Expected 0 certs, got %ld\n", value
);
2961 ret
= CryptMsgGetParam(msg
, CMSG_CRL_COUNT_PARAM
, 0, &value
, &size
);
2962 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2963 ok(value
== 0, "Expected 0 CRLs, got %ld\n", value
);
2965 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, 0, NULL
,
2967 ret
= CryptMsgUpdate(msg
, signedWithCertAndCrlBareContent
,
2968 sizeof(signedWithCertAndCrlBareContent
), TRUE
);
2969 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2970 ret
= CryptMsgGetParam(msg
, CMSG_CERT_COUNT_PARAM
, 0, &value
, &size
);
2971 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2972 ok(value
== 1, "Expected 1 cert, got %ld\n", value
);
2973 check_param("cert", msg
, CMSG_CERT_PARAM
, cert
, sizeof(cert
));
2974 ret
= CryptMsgGetParam(msg
, CMSG_CRL_COUNT_PARAM
, 0, &value
, &size
);
2975 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2976 ok(value
== 1, "Expected 1 CRL, got %ld\n", value
);
2977 check_param("crl", msg
, CMSG_CRL_PARAM
, crl
, sizeof(crl
));
2978 check_param("signed with cert and CRL computed hash", msg
,
2979 CMSG_COMPUTED_HASH_PARAM
, signedWithCertAndCrlComputedHash
,
2980 sizeof(signedWithCertAndCrlComputedHash
));
2983 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
2984 ret
= CryptMsgUpdate(msg
, signedKeyIdEmptyContent
,
2985 sizeof(signedKeyIdEmptyContent
), TRUE
);
2986 if (!ret
&& GetLastError() == OSS_DATA_ERROR
)
2989 win_skip("Subsequent tests crash on some Win9x\n");
2992 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2993 size
= sizeof(value
);
2994 ret
= CryptMsgGetParam(msg
, CMSG_SIGNER_COUNT_PARAM
, 0, &value
, &size
);
2995 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2996 ok(value
== 1, "Expected 1 signer, got %ld\n", value
);
2997 /* Getting the regular (non-CMS) signer info from a CMS message is also
3001 ret
= CryptMsgGetParam(msg
, CMSG_SIGNER_INFO_PARAM
, 0, NULL
, &size
);
3002 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
3004 buf
= CryptMemAlloc(size
);
3009 CMSG_SIGNER_INFO signer
;
3012 /* and here's the little oddity: for a CMS message using the key id
3013 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
3014 * a signer with a zero (not empty) serial number, and whose issuer is
3015 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
3016 * and value of the key id.
3018 signer
.dwVersion
= CMSG_SIGNED_DATA_V3
;
3019 signer
.Issuer
.cbData
= sizeof(keyIdIssuer
);
3020 signer
.Issuer
.pbData
= keyIdIssuer
;
3021 signer
.SerialNumber
.cbData
= 1;
3022 signer
.SerialNumber
.pbData
= &zero
;
3023 CryptMsgGetParam(msg
, CMSG_SIGNER_INFO_PARAM
, 0, buf
, &size
);
3024 compare_signer_info((CMSG_SIGNER_INFO
*)buf
, &signer
);
3028 ret
= CryptMsgGetParam(msg
, CMSG_CMS_SIGNER_INFO_PARAM
, 0, NULL
, &size
);
3029 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
3031 buf
= CryptMemAlloc(size
);
3036 CMSG_CMS_SIGNER_INFO signer
= { 0 };
3038 signer
.dwVersion
= CMSG_SIGNED_DATA_V3
;
3039 signer
.SignerId
.dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
3040 U(signer
.SignerId
).KeyId
.cbData
= sizeof(serialNum
);
3041 U(signer
.SignerId
).KeyId
.pbData
= serialNum
;
3042 signer
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
3043 CryptMsgGetParam(msg
, CMSG_CMS_SIGNER_INFO_PARAM
, 0, buf
, &size
);
3044 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO
*)buf
, &signer
);
3049 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
, 0, NULL
,
3051 CryptMsgUpdate(msg
, envelopedEmptyBareContent
,
3052 sizeof(envelopedEmptyBareContent
), TRUE
);
3053 check_param("enveloped empty bare content", msg
, CMSG_CONTENT_PARAM
, NULL
,
3057 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
3058 CryptMsgUpdate(msg
, envelopedEmptyContent
, sizeof(envelopedEmptyContent
),
3060 check_param("enveloped empty content", msg
, CMSG_CONTENT_PARAM
, NULL
, 0);
3063 CryptAcquireContextA(&hCryptProv
, NULL
, MS_ENHANCED_PROV_A
, PROV_RSA_FULL
,
3064 CRYPT_VERIFYCONTEXT
);
3065 SetLastError(0xdeadbeef);
3066 ret
= CryptImportKey(hCryptProv
, publicPrivateKeyPair
,
3067 sizeof(publicPrivateKeyPair
), 0, 0, &key
);
3069 broken(!ret
&& GetLastError() == NTE_PERM
), /* WinME and some NT4 */
3070 "CryptImportKey failed: %08lx\n", GetLastError());
3072 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
3073 CryptMsgUpdate(msg
, envelopedMessage
, sizeof(envelopedMessage
), TRUE
);
3074 check_param("enveloped message before decrypting", msg
, CMSG_CONTENT_PARAM
,
3075 envelopedMessage
+ sizeof(envelopedMessage
) - 4, 4);
3078 decryptPara
.hCryptProv
= hCryptProv
;
3079 SetLastError(0xdeadbeef);
3080 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_DECRYPT
, &decryptPara
);
3081 ok(ret
, "CryptMsgControl failed: %08lx\n", GetLastError());
3082 decryptPara
.hCryptProv
= 0;
3083 SetLastError(0xdeadbeef);
3084 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_DECRYPT
, &decryptPara
);
3085 ok(!ret
&& GetLastError() == CRYPT_E_ALREADY_DECRYPTED
,
3086 "expected CRYPT_E_ALREADY_DECRYPTED, got %08lx\n", GetLastError());
3087 check_param("enveloped message", msg
, CMSG_CONTENT_PARAM
, msgData
,
3091 win_skip("failed to import a key, skipping tests\n");
3094 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
, 0, NULL
,
3096 CryptMsgUpdate(msg
, envelopedBareMessage
, sizeof(envelopedBareMessage
),
3098 check_param("enveloped bare message before decrypting", msg
,
3099 CMSG_CONTENT_PARAM
, envelopedBareMessage
+
3100 sizeof(envelopedBareMessage
) - 4, 4);
3103 decryptPara
.hCryptProv
= hCryptProv
;
3104 SetLastError(0xdeadbeef);
3105 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_DECRYPT
, &decryptPara
);
3106 ok(ret
, "CryptMsgControl failed: %08lx\n", GetLastError());
3107 check_param("enveloped bare message", msg
, CMSG_CONTENT_PARAM
, msgData
,
3111 win_skip("failed to import a key, skipping tests\n");
3115 CryptDestroyKey(key
);
3116 CryptReleaseContext(hCryptProv
, 0);
3118 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
3119 CryptMsgUpdate(msg
, envelopedMessageWith3Recps
,
3120 sizeof(envelopedMessageWith3Recps
), TRUE
);
3122 check_param("recipient count", msg
, CMSG_RECIPIENT_COUNT_PARAM
,
3123 (const BYTE
*)&value
, sizeof(value
));
3125 SetLastError(0xdeadbeef);
3126 ret
= CryptMsgGetParam(msg
, CMSG_RECIPIENT_INFO_PARAM
, 3, NULL
, &size
);
3127 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_INDEX
,
3128 "expected CRYPT_E_INVALID_INDEX, got %08lx\n", GetLastError());
3130 SetLastError(0xdeadbeef);
3131 ret
= CryptMsgGetParam(msg
, CMSG_RECIPIENT_INFO_PARAM
, 2, NULL
, &size
);
3132 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
3133 ok(size
>= 142, "unexpected size: %lu\n", size
);
3135 buf
= CryptMemAlloc(size
);
3140 CERT_INFO
*certInfo
= (CERT_INFO
*)buf
;
3142 SetLastError(0xdeadbeef);
3143 ret
= CryptMsgGetParam(msg
, CMSG_RECIPIENT_INFO_PARAM
, 2, buf
, &size
);
3144 ok(ret
, "CryptMsgGetParam failed: %08lx\n", GetLastError());
3145 ok(certInfo
->SerialNumber
.cbData
== sizeof(serialNumber
),
3146 "unexpected serial number size: %lu\n", certInfo
->SerialNumber
.cbData
);
3147 ok(!memcmp(certInfo
->SerialNumber
.pbData
, serialNumber
,
3148 sizeof(serialNumber
)), "unexpected serial number\n");
3149 ok(certInfo
->Issuer
.cbData
== sizeof(issuer
),
3150 "unexpected issuer size: %lu\n", certInfo
->Issuer
.cbData
);
3151 ok(!memcmp(certInfo
->Issuer
.pbData
, issuer
, sizeof(issuer
)),
3152 "unexpected issuer\n");
3158 static void test_decode_msg(void)
3160 test_decode_msg_update();
3161 test_decode_msg_get_param();
3164 static BYTE aKey
[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
3165 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
3166 static BYTE encodedPubKey
[] = {
3167 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
3168 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
3170 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
3171 static BYTE mod_encoded
[] = {
3172 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
3175 static void test_msg_control(void)
3177 static char oid_rsa_rsa
[] = szOID_RSA_RSA
;
3181 CERT_INFO certInfo
= { 0 };
3182 CMSG_HASHED_ENCODE_INFO hashInfo
= { 0 };
3183 CMSG_SIGNED_ENCODE_INFO signInfo
= { sizeof(signInfo
), 0 };
3184 CMSG_CTRL_DECRYPT_PARA decryptPara
= { sizeof(decryptPara
), 0 };
3187 ret = CryptMsgControl(NULL, 0, 0, NULL);
3190 /* Data encode messages don't allow any sort of control.. */
3191 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
3193 /* either with no prior update.. */
3194 for (i
= 1; !old_crypt32
&& (i
<= CMSG_CTRL_ADD_CMS_SIGNER_INFO
); i
++)
3196 SetLastError(0xdeadbeef);
3197 ret
= CryptMsgControl(msg
, 0, i
, NULL
);
3198 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3199 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3201 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
3202 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3203 /* or after an update. */
3204 for (i
= 1; !old_crypt32
&& (i
<= CMSG_CTRL_ADD_CMS_SIGNER_INFO
); i
++)
3206 SetLastError(0xdeadbeef);
3207 ret
= CryptMsgControl(msg
, 0, i
, NULL
);
3208 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3209 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3213 /* Hash encode messages don't allow any sort of control.. */
3214 hashInfo
.cbSize
= sizeof(hashInfo
);
3215 hashInfo
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
3216 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
3218 /* either with no prior update.. */
3219 for (i
= 1; !old_crypt32
&& (i
<= CMSG_CTRL_ADD_CMS_SIGNER_INFO
); i
++)
3221 SetLastError(0xdeadbeef);
3222 ret
= CryptMsgControl(msg
, 0, i
, NULL
);
3223 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3224 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3226 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
3227 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3228 /* or after an update. */
3229 for (i
= 1; !old_crypt32
&& (i
<= CMSG_CTRL_ADD_CMS_SIGNER_INFO
); i
++)
3231 SetLastError(0xdeadbeef);
3232 ret
= CryptMsgControl(msg
, 0, i
, NULL
);
3233 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3234 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3238 /* Signed encode messages likewise don't allow any sort of control.. */
3239 signInfo
.cbSize
= sizeof(signInfo
);
3240 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
3242 /* either before an update.. */
3243 for (i
= 1; !old_crypt32
&& (i
<= CMSG_CTRL_ADD_CMS_SIGNER_INFO
); i
++)
3245 SetLastError(0xdeadbeef);
3246 ret
= CryptMsgControl(msg
, 0, i
, NULL
);
3247 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3248 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3250 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
3251 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3252 /* or after an update. */
3253 for (i
= 1; !old_crypt32
&& (i
<= CMSG_CTRL_ADD_CMS_SIGNER_INFO
); i
++)
3255 SetLastError(0xdeadbeef);
3256 ret
= CryptMsgControl(msg
, 0, i
, NULL
);
3257 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3258 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3262 /* Decode messages behave a bit differently. */
3263 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
3264 /* Bad control type */
3265 SetLastError(0xdeadbeef);
3266 ret
= CryptMsgControl(msg
, 0, 0, NULL
);
3267 ok(!ret
&& GetLastError() == CRYPT_E_CONTROL_TYPE
,
3268 "Expected CRYPT_E_CONTROL_TYPE, got %08lx\n", GetLastError());
3269 SetLastError(0xdeadbeef);
3270 ret
= CryptMsgControl(msg
, 1, 0, NULL
);
3271 ok(!ret
&& GetLastError() == CRYPT_E_CONTROL_TYPE
,
3272 "Expected CRYPT_E_CONTROL_TYPE, got %08lx\n", GetLastError());
3273 /* Can't verify the hash of an indeterminate-type message */
3274 SetLastError(0xdeadbeef);
3275 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_HASH
, NULL
);
3276 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
3277 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3279 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
3281 /* Can't decrypt an indeterminate-type message */
3282 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_DECRYPT
, &decryptPara
);
3283 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
3284 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3289 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
3291 /* Can't verify the hash of an empty message */
3292 SetLastError(0xdeadbeef);
3293 /* Crashes on some Win9x */
3294 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_HASH
, NULL
);
3296 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3297 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
3299 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3301 /* Can't verify the signature of a hash message */
3302 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_SIGNATURE
, &certInfo
);
3303 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
3304 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3305 CryptMsgUpdate(msg
, hashEmptyBareContent
, sizeof(hashEmptyBareContent
),
3307 /* Oddly enough, this fails, crashes on some Win9x */
3308 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_HASH
, NULL
);
3309 ok(!ret
, "Expected failure\n");
3312 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
3314 CryptMsgUpdate(msg
, hashBareContent
, sizeof(hashBareContent
), TRUE
);
3315 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_HASH
, NULL
);
3316 ok(ret
, "CryptMsgControl failed: %08lx\n", GetLastError());
3317 /* Can't decrypt an indeterminate-type message */
3318 SetLastError(0xdeadbeef);
3319 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_DECRYPT
, &decryptPara
);
3320 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
3321 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3324 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
, 0, 0,
3326 /* Can't verify the hash of a detached message before it's been updated. */
3327 SetLastError(0xdeadbeef);
3328 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_HASH
, NULL
);
3329 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
3330 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3331 ret
= CryptMsgUpdate(msg
, detachedHashContent
, sizeof(detachedHashContent
),
3333 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3334 /* Still can't verify the hash of a detached message with the content
3335 * of the detached hash given..
3337 SetLastError(0xdeadbeef);
3338 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_HASH
, NULL
);
3339 ok(!ret
&& GetLastError() == CRYPT_E_HASH_VALUE
,
3340 "Expected CRYPT_E_HASH_VALUE, got %08lx\n", GetLastError());
3341 /* and giving the content of the message after attempting to verify the
3344 SetLastError(0xdeadbeef);
3345 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
3348 (GetLastError() == NTE_BAD_HASH_STATE
||
3349 GetLastError() == NTE_BAD_ALGID
|| /* Win9x */
3350 GetLastError() == CRYPT_E_MSG_ERROR
), /* Vista */
3351 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3352 "got %08lx\n", GetLastError());
3355 /* Finally, verifying the hash of a detached message in the correct order:
3356 * 1. Update with the detached hash message
3357 * 2. Update with the content of the message
3358 * 3. Verifying the hash of the message
3361 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
, 0, 0,
3363 ret
= CryptMsgUpdate(msg
, detachedHashContent
, sizeof(detachedHashContent
),
3365 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3366 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
3367 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3368 SetLastError(0xdeadbeef);
3369 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_HASH
, NULL
);
3370 ok(ret
, "CryptMsgControl failed: %08lx\n", GetLastError());
3373 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, 0, NULL
,
3375 /* Can't verify the hash of a signed message */
3376 SetLastError(0xdeadbeef);
3377 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_HASH
, NULL
);
3378 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
3379 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3380 /* Can't decrypt a signed message */
3381 SetLastError(0xdeadbeef);
3382 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_DECRYPT
, &decryptPara
);
3383 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
3384 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3386 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3387 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3389 CryptMsgUpdate(msg
, signedWithCertBareContent
,
3390 sizeof(signedWithCertBareContent
), TRUE
);
3391 /* With an empty cert info, the signer can't be found in the message (and
3392 * the signature can't be verified.
3394 SetLastError(0xdeadbeef);
3395 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_SIGNATURE
, &certInfo
);
3396 ok(!ret
&& (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND
||
3397 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3398 "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08lx\n",
3400 /* The cert info is expected to have an issuer, serial number, and public
3403 certInfo
.SerialNumber
.cbData
= sizeof(serialNum
);
3404 certInfo
.SerialNumber
.pbData
= serialNum
;
3405 certInfo
.Issuer
.cbData
= sizeof(encodedCommonName
);
3406 certInfo
.Issuer
.pbData
= encodedCommonName
;
3407 SetLastError(0xdeadbeef);
3408 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_SIGNATURE
, &certInfo
);
3409 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
3410 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3411 "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08lx\n", GetLastError());
3413 /* This cert has a public key, but it's not in a usable form */
3414 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, 0, NULL
,
3416 ret
= CryptMsgUpdate(msg
, signedWithCertWithPubKeyBareContent
,
3417 sizeof(signedWithCertWithPubKeyBareContent
), TRUE
);
3420 /* Crashes on some Win9x */
3421 /* Again, cert info needs to have a public key set */
3422 SetLastError(0xdeadbeef);
3423 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_SIGNATURE
, &certInfo
);
3425 (GetLastError() == CRYPT_E_ASN1_EOD
||
3426 GetLastError() == TRUST_E_NOSIGNATURE
/* Vista */),
3427 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08lx\n", GetLastError());
3428 /* The public key is supposed to be in encoded form.. */
3429 certInfo
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= oid_rsa_rsa
;
3430 certInfo
.SubjectPublicKeyInfo
.PublicKey
.cbData
= sizeof(aKey
);
3431 certInfo
.SubjectPublicKeyInfo
.PublicKey
.pbData
= aKey
;
3432 SetLastError(0xdeadbeef);
3433 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_SIGNATURE
, &certInfo
);
3435 (GetLastError() == CRYPT_E_ASN1_BADTAG
||
3436 GetLastError() == TRUST_E_NOSIGNATURE
/* Vista */),
3437 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08lx\n", GetLastError());
3438 /* but not as a X509_PUBLIC_KEY_INFO.. */
3439 certInfo
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= NULL
;
3440 certInfo
.SubjectPublicKeyInfo
.PublicKey
.cbData
= sizeof(encodedPubKey
);
3441 certInfo
.SubjectPublicKeyInfo
.PublicKey
.pbData
= encodedPubKey
;
3442 SetLastError(0xdeadbeef);
3443 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_SIGNATURE
, &certInfo
);
3445 (GetLastError() == CRYPT_E_ASN1_BADTAG
||
3446 GetLastError() == TRUST_E_NOSIGNATURE
/* Vista */),
3447 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08lx\n", GetLastError());
3448 /* This decodes successfully, but it doesn't match any key in the message */
3449 certInfo
.SubjectPublicKeyInfo
.PublicKey
.cbData
= sizeof(mod_encoded
);
3450 certInfo
.SubjectPublicKeyInfo
.PublicKey
.pbData
= mod_encoded
;
3451 SetLastError(0xdeadbeef);
3452 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_SIGNATURE
, &certInfo
);
3453 /* In Wine's rsaenh, this fails to decode because the key length is too
3454 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
3459 (GetLastError() == NTE_BAD_SIGNATURE
||
3460 GetLastError() == TRUST_E_NOSIGNATURE
/* Vista */),
3461 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08lx\n", GetLastError());
3464 /* A message with no data doesn't have a valid signature */
3465 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
3466 ret
= CryptMsgUpdate(msg
, signedWithCertWithValidPubKeyEmptyContent
,
3467 sizeof(signedWithCertWithValidPubKeyEmptyContent
), TRUE
);
3470 certInfo
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= oid_rsa_rsa
;
3471 certInfo
.SubjectPublicKeyInfo
.PublicKey
.cbData
= sizeof(pubKey
);
3472 certInfo
.SubjectPublicKeyInfo
.PublicKey
.pbData
= pubKey
;
3473 SetLastError(0xdeadbeef);
3474 /* Crashes on some Win9x */
3475 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_SIGNATURE
, &certInfo
);
3477 (GetLastError() == NTE_BAD_SIGNATURE
||
3478 GetLastError() == TRUST_E_NOSIGNATURE
/* Vista */),
3479 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08lx\n", GetLastError());
3482 /* Finally, this succeeds */
3483 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
3484 CryptMsgUpdate(msg
, signedWithCertWithValidPubKeyContent
,
3485 sizeof(signedWithCertWithValidPubKeyContent
), TRUE
);
3486 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_SIGNATURE
, &certInfo
);
3487 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3488 "CryptMsgControl failed: %08lx\n", GetLastError());
3491 /* Test verifying signature of a detached signed message */
3492 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
, 0, 0,
3494 ret
= CryptMsgUpdate(msg
, detachedSignedContent
,
3495 sizeof(detachedSignedContent
), TRUE
);
3496 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3497 /* Can't verify the sig without having updated the data */
3498 SetLastError(0xdeadbeef);
3499 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_SIGNATURE
, &certInfo
);
3500 ok(!ret
&& (GetLastError() == NTE_BAD_SIGNATURE
||
3501 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3502 "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08lx\n",
3504 /* Now that the signature's been checked, can't do the final update */
3505 SetLastError(0xdeadbeef);
3506 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
3509 (GetLastError() == NTE_BAD_HASH_STATE
||
3510 GetLastError() == NTE_BAD_ALGID
|| /* Win9x */
3511 GetLastError() == CRYPT_E_MSG_ERROR
)) || /* Vista */
3512 broken(ret
), /* Win9x */
3513 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3514 "got %08lx\n", GetLastError());
3516 /* Updating with the detached portion of the message and the data of the
3517 * the message allows the sig to be verified.
3519 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
, 0, 0,
3521 ret
= CryptMsgUpdate(msg
, detachedSignedContent
,
3522 sizeof(detachedSignedContent
), TRUE
);
3523 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3524 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
3525 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3526 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_VERIFY_SIGNATURE
, &certInfo
);
3527 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3528 "CryptMsgControl failed: %08lx\n", GetLastError());
3531 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
, 0, NULL
,
3533 decryptPara
.cbSize
= 0;
3534 SetLastError(0xdeadbeef);
3535 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_DECRYPT
, &decryptPara
);
3536 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3537 "expected E_INVALIDARG, got %08lx\n", GetLastError());
3538 decryptPara
.cbSize
= sizeof(decryptPara
);
3541 SetLastError(0xdeadbeef);
3542 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_DECRYPT
, &decryptPara
);
3543 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
3544 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3546 SetLastError(0xdeadbeef);
3547 ret
= CryptMsgUpdate(msg
, envelopedEmptyBareContent
,
3548 sizeof(envelopedEmptyBareContent
), TRUE
);
3549 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3550 SetLastError(0xdeadbeef);
3551 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_DECRYPT
, &decryptPara
);
3552 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_INDEX
,
3553 "expected CRYPT_E_INVALID_INDEX, got %08lx\n", GetLastError());
3556 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
, 0, NULL
,
3558 SetLastError(0xdeadbeef);
3559 ret
= CryptMsgUpdate(msg
, envelopedBareMessage
,
3560 sizeof(envelopedBareMessage
), TRUE
);
3561 ok(ret
, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3562 SetLastError(0xdeadbeef);
3563 ret
= CryptMsgControl(msg
, 0, CMSG_CTRL_DECRYPT
, &decryptPara
);
3564 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
3565 "expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
3569 static void test_msg_get_and_verify_signer(void)
3573 PCCERT_CONTEXT signer
;
3580 CryptMsgGetAndVerifySigner(NULL
, 0, NULL
, 0, NULL
, NULL
);
3581 CryptMsgGetAndVerifySigner(NULL
, 0, NULL
, 0, NULL
, &signerIndex
);
3584 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
3585 /* An empty message has no signer */
3586 SetLastError(0xdeadbeef);
3587 ret
= CryptMsgGetAndVerifySigner(msg
, 0, NULL
, 0, NULL
, NULL
);
3588 ok(!ret
&& GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER
,
3589 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3590 /* The signer is cleared on error */
3591 signer
= (PCCERT_CONTEXT
)0xdeadbeef;
3592 SetLastError(0xdeadbeef);
3593 ret
= CryptMsgGetAndVerifySigner(msg
, 0, NULL
, 0, &signer
, NULL
);
3594 ok(!ret
&& GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER
,
3595 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3596 ok(!signer
, "expected signer to be NULL\n");
3597 /* The signer index is also cleared on error */
3598 signerIndex
= 0xdeadbeef;
3599 SetLastError(0xdeadbeef);
3600 ret
= CryptMsgGetAndVerifySigner(msg
, 0, NULL
, 0, NULL
, &signerIndex
);
3601 ok(!ret
&& GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER
,
3602 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3603 ok(!signerIndex
, "expected 0, got %ld\n", signerIndex
);
3604 /* An unsigned message (msgData isn't a signed message at all)
3605 * likewise has no signer.
3607 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
3608 SetLastError(0xdeadbeef);
3609 ret
= CryptMsgGetAndVerifySigner(msg
, 0, NULL
, 0, NULL
, NULL
);
3610 ok(!ret
&& GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER
,
3611 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3614 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
3615 /* A "signed" message created with no signer cert likewise has no signer */
3616 ret
= CryptMsgUpdate(msg
, signedEmptyContent
, sizeof(signedEmptyContent
), TRUE
);
3619 /* Crashes on most Win9x */
3620 ret
= CryptMsgGetAndVerifySigner(msg
, 0, NULL
, 0, NULL
, NULL
);
3621 ok(!ret
&& GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER
,
3622 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3626 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
3627 /* A signed message succeeds, .. */
3628 CryptMsgUpdate(msg
, signedWithCertWithValidPubKeyContent
,
3629 sizeof(signedWithCertWithValidPubKeyContent
), TRUE
);
3630 ret
= CryptMsgGetAndVerifySigner(msg
, 0, NULL
, 0, NULL
, NULL
);
3631 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3632 "CryptMsgGetAndVerifySigner failed: 0x%08lx\n", GetLastError());
3633 /* the signer index can be retrieved, .. */
3634 signerIndex
= 0xdeadbeef;
3635 ret
= CryptMsgGetAndVerifySigner(msg
, 0, NULL
, 0, NULL
, &signerIndex
);
3636 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3637 "CryptMsgGetAndVerifySigner failed: 0x%08lx\n", GetLastError());
3639 ok(signerIndex
== 0, "expected 0, got %ld\n", signerIndex
);
3640 /* as can the signer cert. */
3641 signer
= (PCCERT_CONTEXT
)0xdeadbeef;
3642 ret
= CryptMsgGetAndVerifySigner(msg
, 0, NULL
, 0, &signer
, NULL
);
3643 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3644 "CryptMsgGetAndVerifySigner failed: 0x%08lx\n", GetLastError());
3646 ok(signer
!= NULL
&& signer
!= (PCCERT_CONTEXT
)0xdeadbeef,
3647 "expected a valid signer\n");
3648 if (signer
&& signer
!= (PCCERT_CONTEXT
)0xdeadbeef)
3649 CertFreeCertificateContext(signer
);
3650 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3652 signerIndex
= 0xdeadbeef;
3653 SetLastError(0xdeadbeef);
3654 ret
= CryptMsgGetAndVerifySigner(msg
, 0, NULL
, CMSG_USE_SIGNER_INDEX_FLAG
,
3655 NULL
, &signerIndex
);
3656 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_INDEX
,
3657 "expected CRYPT_E_INVALID_INDEX, got 0x%08lx\n", GetLastError());
3658 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3659 * message signer not to be found.
3661 SetLastError(0xdeadbeef);
3662 ret
= CryptMsgGetAndVerifySigner(msg
, 0, NULL
, CMSG_TRUSTED_SIGNER_FLAG
,
3664 ok(!ret
&& (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER
||
3665 broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */)),
3666 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3667 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3668 * the message signer not to be found.
3670 store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
3671 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
3672 SetLastError(0xdeadbeef);
3673 ret
= CryptMsgGetAndVerifySigner(msg
, 1, &store
, CMSG_TRUSTED_SIGNER_FLAG
,
3675 ok(!ret
&& (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER
||
3676 broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */)),
3677 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3678 ret
= CertAddEncodedCertificateToStore(store
, X509_ASN_ENCODING
,
3679 v1CertWithValidPubKey
, sizeof(v1CertWithValidPubKey
),
3680 CERT_STORE_ADD_ALWAYS
, NULL
);
3681 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win98 */),
3682 "CertAddEncodedCertificateToStore failed: 0x%08lx\n", GetLastError());
3683 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3684 * the signer succeeds.
3686 SetLastError(0xdeadbeef);
3687 ret
= CryptMsgGetAndVerifySigner(msg
, 1, &store
, CMSG_TRUSTED_SIGNER_FLAG
,
3689 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3690 "CryptMsgGetAndVerifySigner failed: 0x%08lx\n", GetLastError());
3691 CertCloseStore(store
, 0);
3697 /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
3698 if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
3700 win_skip("Some tests will crash on older crypt32 implementations\n");
3704 /* Basic parameter checking tests */
3705 test_msg_open_to_encode();
3706 test_msg_open_to_decode();
3707 test_msg_get_param();
3711 /* Message-type specific tests */
3715 test_enveloped_msg();
3718 test_msg_get_and_verify_signer();