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
28 #include "wine/test.h"
30 static char oid_rsa_md5
[] = szOID_RSA_MD5
;
32 static void test_msg_open_to_encode(void)
37 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
39 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
41 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
46 SetLastError(0xdeadbeef);
47 msg
= CryptMsgOpenToEncode(0, 0, 0, NULL
, NULL
, NULL
);
48 ok(!msg
&& GetLastError() == E_INVALIDARG
,
49 "Expected E_INVALIDARG, got %x\n", GetLastError());
50 SetLastError(0xdeadbeef);
51 msg
= CryptMsgOpenToEncode(X509_ASN_ENCODING
, 0, 0, NULL
, NULL
, NULL
);
52 ok(!msg
&& GetLastError() == E_INVALIDARG
,
53 "Expected E_INVALIDARG, got %x\n", GetLastError());
55 /* Bad message types */
56 SetLastError(0xdeadbeef);
57 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, 0, NULL
, NULL
, NULL
);
58 ok(!msg
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
59 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
60 SetLastError(0xdeadbeef);
61 msg
= CryptMsgOpenToEncode(X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
, 0, 0,
63 ok(!msg
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
64 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
65 SetLastError(0xdeadbeef);
66 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0,
67 CMSG_SIGNED_AND_ENVELOPED
, NULL
, NULL
, NULL
);
68 ok(!msg
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
69 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
70 SetLastError(0xdeadbeef);
71 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENCRYPTED
, NULL
,
73 ok(!msg
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
74 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
77 static void test_msg_open_to_decode(void)
80 CMSG_STREAM_INFO streamInfo
= { 0 };
82 SetLastError(0xdeadbeef);
83 msg
= CryptMsgOpenToDecode(0, 0, 0, 0, NULL
, NULL
);
84 ok(!msg
&& GetLastError() == E_INVALIDARG
,
85 "Expected E_INVALIDARG, got %x\n", GetLastError());
88 SetLastError(0xdeadbeef);
89 msg
= CryptMsgOpenToDecode(X509_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
90 ok(!msg
&& GetLastError() == E_INVALIDARG
,
91 "Expected E_INVALIDARG, got %x\n", GetLastError());
92 SetLastError(0xdeadbeef);
93 msg
= CryptMsgOpenToDecode(X509_ASN_ENCODING
, 0, CMSG_DATA
, 0, NULL
, NULL
);
94 ok(!msg
&& GetLastError() == E_INVALIDARG
,
95 "Expected E_INVALIDARG, got %x\n", GetLastError());
97 /* The message type can be explicit... */
98 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, 0, NULL
,
100 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
102 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
, 0, NULL
,
104 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
106 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
108 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
110 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, 0, NULL
,
112 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
114 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0,
115 CMSG_SIGNED_AND_ENVELOPED
, 0, NULL
, NULL
);
116 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
119 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
120 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
122 /* or even invalid. */
123 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENCRYPTED
, 0, NULL
,
125 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
127 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 1000, 0, NULL
, NULL
);
128 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
131 /* And even though the stream info parameter "must be set to NULL" for
132 * CMSG_HASHED, it's still accepted.
134 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
136 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
140 static void test_msg_get_param(void)
144 DWORD size
, i
, value
;
145 CMSG_SIGNED_ENCODE_INFO signInfo
= { sizeof(signInfo
), 0 };
146 CMSG_SIGNER_ENCODE_INFO signer
= { sizeof(signer
), 0 };
149 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
150 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
151 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
154 /* Decoded messages */
155 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
156 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
157 /* For decoded messages, the type is always available */
159 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, NULL
, &size
);
160 ok(ret
, "CryptMsgGetParam failed: %x\n", GetLastError());
161 size
= sizeof(value
);
162 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, (LPBYTE
)&value
, &size
);
163 ok(ret
, "CryptMsgGetParam failed: %x\n", GetLastError());
164 /* For this (empty) message, the type isn't set */
165 ok(value
== 0, "Expected type 0, got %d\n", value
);
168 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, 0, NULL
,
170 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
171 /* For explicitly typed messages, the type is known. */
172 size
= sizeof(value
);
173 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, (LPBYTE
)&value
, &size
);
174 ok(ret
, "CryptMsgGetParam failed: %x\n", GetLastError());
175 ok(value
== CMSG_DATA
, "Expected CMSG_DATA, got %d\n", value
);
176 for (i
= CMSG_CONTENT_PARAM
; i
<= CMSG_CMS_SIGNER_INFO_PARAM
; i
++)
179 ret
= CryptMsgGetParam(msg
, i
, 0, NULL
, &size
);
180 ok(!ret
, "Parameter %d: expected failure\n", i
);
184 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENVELOPED
, 0, NULL
,
186 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
187 size
= sizeof(value
);
188 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, (LPBYTE
)&value
, &size
);
189 ok(ret
, "CryptMsgGetParam failed: %x\n", GetLastError());
190 ok(value
== CMSG_ENVELOPED
, "Expected CMSG_ENVELOPED, got %d\n", value
);
191 for (i
= CMSG_CONTENT_PARAM
; i
<= CMSG_CMS_SIGNER_INFO_PARAM
; i
++)
194 ret
= CryptMsgGetParam(msg
, i
, 0, NULL
, &size
);
195 ok(!ret
, "Parameter %d: expected failure\n", i
);
199 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
201 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
202 size
= sizeof(value
);
203 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, (LPBYTE
)&value
, &size
);
204 ok(ret
, "CryptMsgGetParam failed: %x\n", GetLastError());
205 ok(value
== CMSG_HASHED
, "Expected CMSG_HASHED, got %d\n", value
);
206 for (i
= CMSG_CONTENT_PARAM
; i
<= CMSG_CMS_SIGNER_INFO_PARAM
; i
++)
209 ret
= CryptMsgGetParam(msg
, i
, 0, NULL
, &size
);
210 ok(!ret
, "Parameter %d: expected failure\n", i
);
214 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, 0, NULL
,
216 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
217 size
= sizeof(value
);
218 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, (LPBYTE
)&value
, &size
);
219 ok(ret
, "CryptMsgGetParam failed: %x\n", GetLastError());
220 ok(value
== CMSG_SIGNED
, "Expected CMSG_SIGNED, got %d\n", value
);
221 for (i
= CMSG_CONTENT_PARAM
; i
<= CMSG_CMS_SIGNER_INFO_PARAM
; i
++)
224 ret
= CryptMsgGetParam(msg
, i
, 0, NULL
, &size
);
225 ok(!ret
, "Parameter %d: expected failure\n", i
);
229 /* Explicitly typed messages get their types set, even if they're invalid */
230 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_ENCRYPTED
, 0, NULL
,
232 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
233 size
= sizeof(value
);
234 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, (LPBYTE
)&value
, &size
);
235 ok(ret
, "CryptMsgGetParam failed: %x\n", GetLastError());
236 ok(value
== CMSG_ENCRYPTED
, "Expected CMSG_ENCRYPTED, got %d\n", value
);
239 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 1000, 0, NULL
, NULL
);
240 ok(msg
!= NULL
, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
241 size
= sizeof(value
);
242 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, (LPBYTE
)&value
, &size
);
243 ok(ret
, "CryptMsgGetParam failed: %x\n", GetLastError());
244 ok(value
== 1000, "Expected 1000, got %d\n", value
);
248 static void test_msg_close(void)
253 /* NULL succeeds.. */
254 ret
= CryptMsgClose(NULL
);
255 ok(ret
, "CryptMsgClose failed: %x\n", GetLastError());
256 /* but an arbitrary pointer crashes. */
258 ret
= CryptMsgClose((HCRYPTMSG
)1);
259 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
261 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
262 ret
= CryptMsgClose(msg
);
263 ok(ret
, "CryptMsgClose failed: %x\n", GetLastError());
266 static void check_param(LPCSTR test
, HCRYPTMSG msg
, DWORD param
,
267 const BYTE
*expected
, DWORD expectedSize
)
274 ret
= CryptMsgGetParam(msg
, param
, 0, NULL
, &size
);
275 ok(ret
, "%s: CryptMsgGetParam failed: %08x\n", test
, GetLastError());
276 buf
= HeapAlloc(GetProcessHeap(), 0, size
);
277 ret
= CryptMsgGetParam(msg
, param
, 0, buf
, &size
);
278 ok(ret
, "%s: CryptMsgGetParam failed: %08x\n", test
, GetLastError());
279 ok(size
== expectedSize
, "%s: expected size %d, got %d\n", test
,
281 if (size
== expectedSize
&& size
)
282 ok(!memcmp(buf
, expected
, size
), "%s: unexpected data\n", test
);
283 HeapFree(GetProcessHeap(), 0, buf
);
286 static void test_data_msg_open(void)
289 CMSG_HASHED_ENCODE_INFO hashInfo
= { 0 };
290 CMSG_STREAM_INFO streamInfo
= { 0 };
291 char oid
[] = "1.2.3";
293 /* The data message type takes no additional info */
294 SetLastError(0xdeadbeef);
295 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, &hashInfo
,
297 ok(!msg
&& GetLastError() == E_INVALIDARG
,
298 "Expected E_INVALIDARG, got %x\n", GetLastError());
299 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
301 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
304 /* An empty stream info is allowed. */
305 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
307 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
310 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
311 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, oid
,
313 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
315 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
316 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
317 CMSG_DATA
, NULL
, oid
, NULL
);
318 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
320 /* and when a stream info is given, even though you're not supposed to be
321 * able to use anything but szOID_RSA_data when streaming is being used.
323 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
324 CMSG_DATA
, NULL
, oid
, &streamInfo
);
325 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
329 static const BYTE msgData
[] = { 1, 2, 3, 4 };
331 static BOOL WINAPI
nop_stream_output(const void *pvArg
, BYTE
*pb
, DWORD cb
,
337 static void test_data_msg_update(void)
341 CMSG_STREAM_INFO streamInfo
= { 0 };
343 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
345 /* Can't update a message that wasn't opened detached with final = FALSE */
346 SetLastError(0xdeadbeef);
347 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
348 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
349 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
350 /* Updating it with final = TRUE succeeds */
351 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
352 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
353 /* Any subsequent update will fail, as the last was final */
354 SetLastError(0xdeadbeef);
355 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
356 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
357 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
360 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
362 /* Can't update a message with no data */
363 SetLastError(0xdeadbeef);
364 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
365 ok(!ret
&& GetLastError() == E_INVALIDARG
,
366 "Expected E_INVALIDARG, got %x\n", GetLastError());
367 /* Curiously, a valid update will now fail as well, presumably because of
368 * the last (invalid, but final) update.
370 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
371 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
372 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
375 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
376 CMSG_DATA
, NULL
, NULL
, NULL
);
377 /* Doesn't appear to be able to update CMSG-DATA with non-final updates */
378 SetLastError(0xdeadbeef);
379 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
380 ok(!ret
&& GetLastError() == E_INVALIDARG
,
381 "Expected E_INVALIDARG, got %x\n", GetLastError());
382 SetLastError(0xdeadbeef);
383 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
384 ok(!ret
&& GetLastError() == E_INVALIDARG
,
385 "Expected E_INVALIDARG, got %x\n", GetLastError());
386 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
387 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
390 /* Calling update after opening with an empty stream info (with a bogus
391 * output function) yields an error:
393 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
395 SetLastError(0xdeadbeef);
396 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
397 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
398 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
400 /* Calling update with a valid output function succeeds, even if the data
401 * exceeds the size specified in the stream info.
403 streamInfo
.pfnStreamOutput
= nop_stream_output
;
404 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
406 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
407 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
408 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
409 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
413 static void test_data_msg_get_param(void)
418 CMSG_STREAM_INFO streamInfo
= { 0, nop_stream_output
, NULL
};
420 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
423 /* Content and bare content are always gettable when not streaming */
425 ret
= CryptMsgGetParam(msg
, CMSG_CONTENT_PARAM
, 0, NULL
, &size
);
426 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
428 ret
= CryptMsgGetParam(msg
, CMSG_BARE_CONTENT_PARAM
, 0, NULL
, &size
);
429 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
430 /* But for this type of message, the signer and hash aren't applicable,
431 * and the type isn't available.
434 SetLastError(0xdeadbeef);
435 ret
= CryptMsgGetParam(msg
, CMSG_ENCODED_SIGNER
, 0, NULL
, &size
);
436 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
437 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
438 SetLastError(0xdeadbeef);
439 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, NULL
, &size
);
440 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
441 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
442 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, NULL
, &size
);
443 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
444 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
447 /* Can't get content or bare content when streaming */
448 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
,
450 SetLastError(0xdeadbeef);
451 ret
= CryptMsgGetParam(msg
, CMSG_BARE_CONTENT_PARAM
, 0, NULL
, &size
);
452 ok(!ret
&& GetLastError() == E_INVALIDARG
,
453 "Expected E_INVALIDARG, got %x\n", GetLastError());
454 SetLastError(0xdeadbeef);
455 ret
= CryptMsgGetParam(msg
, CMSG_CONTENT_PARAM
, 0, NULL
, &size
);
456 ok(!ret
&& GetLastError() == E_INVALIDARG
,
457 "Expected E_INVALIDARG, got %x\n", GetLastError());
461 static const BYTE dataEmptyBareContent
[] = { 0x04,0x00 };
462 static const BYTE dataEmptyContent
[] = {
463 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
465 static const BYTE dataBareContent
[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
466 static const BYTE dataContent
[] = {
467 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
468 0x04,0x04,0x01,0x02,0x03,0x04 };
473 CRYPT_DATA_BLOB
*updates
;
476 static BOOL WINAPI
accumulating_stream_output(const void *pvArg
, BYTE
*pb
,
477 DWORD cb
, BOOL final
)
479 struct update_accum
*accum
= (struct update_accum
*)pvArg
;
483 accum
->updates
= CryptMemRealloc(accum
->updates
,
484 (accum
->cUpdates
+ 1) * sizeof(CRYPT_DATA_BLOB
));
486 accum
->updates
= CryptMemAlloc(sizeof(CRYPT_DATA_BLOB
));
489 CRYPT_DATA_BLOB
*blob
= &accum
->updates
[accum
->cUpdates
];
491 blob
->pbData
= CryptMemAlloc(cb
);
494 memcpy(blob
->pbData
, pb
, cb
);
503 /* The updates of a (bogus) definite-length encoded message */
504 static BYTE u1
[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
505 0x07,0x01,0xa0,0x02,0x04,0x00 };
506 static BYTE u2
[] = { 0x01,0x02,0x03,0x04 };
507 static CRYPT_DATA_BLOB b1
[] = {
512 static const struct update_accum a1
= { sizeof(b1
) / sizeof(b1
[0]), b1
};
513 /* The updates of a definite-length encoded message */
514 static BYTE u3
[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
515 0x07,0x01,0xa0,0x06,0x04,0x04 };
516 static CRYPT_DATA_BLOB b2
[] = {
520 static const struct update_accum a2
= { sizeof(b2
) / sizeof(b2
[0]), b2
};
521 /* The updates of an indefinite-length encoded message */
522 static BYTE u4
[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
523 0x07,0x01,0xa0,0x80,0x24,0x80 };
524 static BYTE u5
[] = { 0x04,0x04 };
525 static BYTE u6
[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
526 static CRYPT_DATA_BLOB b3
[] = {
534 static const struct update_accum a3
= { sizeof(b3
) / sizeof(b3
[0]), b3
};
536 static void check_updates(LPCSTR header
, const struct update_accum
*expected
,
537 const struct update_accum
*got
)
541 ok(expected
->cUpdates
== got
->cUpdates
,
542 "%s: expected %d updates, got %d\n", header
, expected
->cUpdates
,
544 if (expected
->cUpdates
== got
->cUpdates
)
545 for (i
= 0; i
< min(expected
->cUpdates
, got
->cUpdates
); i
++)
547 ok(expected
->updates
[i
].cbData
== got
->updates
[i
].cbData
,
548 "%s, update %d: expected %d bytes, got %d\n", header
, i
,
549 expected
->updates
[i
].cbData
, got
->updates
[i
].cbData
);
550 if (expected
->updates
[i
].cbData
&& expected
->updates
[i
].cbData
==
551 got
->updates
[i
].cbData
)
552 ok(!memcmp(expected
->updates
[i
].pbData
, got
->updates
[i
].pbData
,
553 got
->updates
[i
].cbData
), "%s, update %d: unexpected value\n",
558 /* Frees the updates stored in accum */
559 static void free_updates(struct update_accum
*accum
)
563 for (i
= 0; i
< accum
->cUpdates
; i
++)
564 CryptMemFree(accum
->updates
[i
].pbData
);
565 CryptMemFree(accum
->updates
);
566 accum
->updates
= NULL
;
570 static void test_data_msg_encoding(void)
574 static char oid
[] = "1.2.3";
575 struct update_accum accum
= { 0, NULL
};
576 CMSG_STREAM_INFO streamInfo
= { 0, accumulating_stream_output
, &accum
};
578 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, NULL
,
580 check_param("data empty bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
581 dataEmptyBareContent
, sizeof(dataEmptyBareContent
));
582 check_param("data empty content", msg
, CMSG_CONTENT_PARAM
, dataEmptyContent
,
583 sizeof(dataEmptyContent
));
584 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
585 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
586 check_param("data bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
587 dataBareContent
, sizeof(dataBareContent
));
588 check_param("data content", msg
, CMSG_CONTENT_PARAM
, dataContent
,
589 sizeof(dataContent
));
591 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
592 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_BARE_CONTENT_FLAG
,
593 CMSG_DATA
, NULL
, NULL
, NULL
);
594 check_param("data empty bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
595 dataEmptyBareContent
, sizeof(dataEmptyBareContent
));
596 check_param("data empty content", msg
, CMSG_CONTENT_PARAM
, dataEmptyContent
,
597 sizeof(dataEmptyContent
));
598 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
599 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
600 check_param("data bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
601 dataBareContent
, sizeof(dataBareContent
));
602 check_param("data content", msg
, CMSG_CONTENT_PARAM
, dataContent
,
603 sizeof(dataContent
));
605 /* The inner OID is apparently ignored */
606 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
, oid
,
608 check_param("data bogus oid bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
609 dataEmptyBareContent
, sizeof(dataEmptyBareContent
));
610 check_param("data bogus oid content", msg
, CMSG_CONTENT_PARAM
,
611 dataEmptyContent
, sizeof(dataEmptyContent
));
612 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
613 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
614 check_param("data bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
615 dataBareContent
, sizeof(dataBareContent
));
616 check_param("data content", msg
, CMSG_CONTENT_PARAM
, dataContent
,
617 sizeof(dataContent
));
619 /* A streaming message is DER encoded if the length is not 0xffffffff, but
620 * curiously, updates aren't validated to make sure they don't exceed the
621 * stated length. (The resulting output will of course fail to decode.)
623 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
,
625 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
626 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
628 check_updates("bogus data message with definite length", &a1
, &accum
);
629 free_updates(&accum
);
630 /* A valid definite-length encoding: */
631 streamInfo
.cbContent
= sizeof(msgData
);
632 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
,
634 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
636 check_updates("data message with definite length", &a2
, &accum
);
637 free_updates(&accum
);
638 /* An indefinite-length encoding: */
639 streamInfo
.cbContent
= 0xffffffff;
640 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, NULL
,
642 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
643 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
646 check_updates("data message with indefinite length", &a3
, &accum
);
647 free_updates(&accum
);
650 static void test_data_msg(void)
652 test_data_msg_open();
653 test_data_msg_update();
654 test_data_msg_get_param();
655 test_data_msg_encoding();
658 static void test_hash_msg_open(void)
661 CMSG_HASHED_ENCODE_INFO hashInfo
= { 0 };
662 CMSG_STREAM_INFO streamInfo
= { 0, nop_stream_output
, NULL
};
664 SetLastError(0xdeadbeef);
665 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
667 ok(!msg
&& GetLastError() == E_INVALIDARG
,
668 "Expected E_INVALIDARG, got %x\n", GetLastError());
669 hashInfo
.cbSize
= sizeof(hashInfo
);
670 SetLastError(0xdeadbeef);
671 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
673 ok(!msg
&& GetLastError() == CRYPT_E_UNKNOWN_ALGO
,
674 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
675 hashInfo
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
676 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
678 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
680 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
681 CMSG_HASHED
, &hashInfo
, NULL
, NULL
);
682 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
684 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
685 CMSG_HASHED
, &hashInfo
, NULL
, &streamInfo
);
686 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
690 static void test_hash_msg_update(void)
694 CMSG_HASHED_ENCODE_INFO hashInfo
= { sizeof(hashInfo
), 0,
695 { oid_rsa_md5
, { 0, NULL
} }, NULL
};
696 CMSG_STREAM_INFO streamInfo
= { 0, nop_stream_output
, NULL
};
698 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
699 CMSG_HASHED
, &hashInfo
, NULL
, NULL
);
700 /* Detached hashed messages opened in non-streaming mode allow non-final
703 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
704 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
705 /* including non-final updates with no data.. */
706 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
707 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
708 /* and final updates with no data. */
709 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
710 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
711 /* But no updates are allowed after the final update. */
712 SetLastError(0xdeadbeef);
713 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
714 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
715 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
716 SetLastError(0xdeadbeef);
717 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
718 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
719 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
721 /* Non-detached messages, in contrast, don't allow non-final updates in
722 * non-streaming mode.
724 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
726 SetLastError(0xdeadbeef);
727 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
728 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
729 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
730 /* Final updates (including empty ones) are allowed. */
731 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
732 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
734 /* And, of course, streaming mode allows non-final updates */
735 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
737 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
738 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
740 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
741 * to be a bug, it isn't actually used - see encoding tests.)
743 streamInfo
.pfnStreamOutput
= NULL
;
744 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
746 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
747 ok(ret
, "CryptMsgUpdate failed: %08x\n", GetLastError());
751 static const BYTE emptyHashParam
[] = {
752 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
755 static void test_hash_msg_get_param(void)
759 CMSG_HASHED_ENCODE_INFO hashInfo
= { sizeof(hashInfo
), 0,
760 { oid_rsa_md5
, { 0, NULL
} }, NULL
};
762 CMSG_STREAM_INFO streamInfo
= { 0, nop_stream_output
, NULL
};
765 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
767 /* Content and bare content are always gettable for non-streamed messages */
769 ret
= CryptMsgGetParam(msg
, CMSG_CONTENT_PARAM
, 0, NULL
, &size
);
770 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
772 ret
= CryptMsgGetParam(msg
, CMSG_BARE_CONTENT_PARAM
, 0, NULL
, &size
);
773 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
774 /* The hash is also available. */
776 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, NULL
, &size
);
777 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
778 ok(size
== sizeof(buf
), "Unexpected size %d\n", size
);
779 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, buf
, &size
);
780 if (size
== sizeof(buf
))
781 ok(!memcmp(buf
, emptyHashParam
, size
), "Unexpected value\n");
782 /* By getting the hash, further updates are not allowed */
783 SetLastError(0xdeadbeef);
784 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
785 ok(!ret
&& GetLastError() == NTE_BAD_HASH_STATE
,
786 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
787 /* The version is also available, and should be zero for this message. */
789 ret
= CryptMsgGetParam(msg
, CMSG_VERSION_PARAM
, 0, NULL
, &size
);
790 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
791 size
= sizeof(value
);
792 ret
= CryptMsgGetParam(msg
, CMSG_VERSION_PARAM
, 0, (LPBYTE
)&value
, &size
);
793 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
794 ok(value
== 0, "Expected version 0, got %d\n", value
);
795 /* As usual, the type isn't available. */
796 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, NULL
, &size
);
797 ok(!ret
, "Expected failure\n");
800 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
802 /* Streamed messages don't allow you to get the content or bare content. */
803 SetLastError(0xdeadbeef);
804 ret
= CryptMsgGetParam(msg
, CMSG_CONTENT_PARAM
, 0, NULL
, &size
);
805 ok(!ret
&& GetLastError() == E_INVALIDARG
,
806 "Expected E_INVALIDARG, got %x\n", GetLastError());
807 SetLastError(0xdeadbeef);
808 ret
= CryptMsgGetParam(msg
, CMSG_BARE_CONTENT_PARAM
, 0, NULL
, &size
);
809 ok(!ret
&& GetLastError() == E_INVALIDARG
,
810 "Expected E_INVALIDARG, got %x\n", GetLastError());
811 /* The hash is still available. */
813 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, NULL
, &size
);
814 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
815 ok(size
== sizeof(buf
), "Unexpected size %d\n", size
);
816 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, buf
, &size
);
817 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
818 if (size
== sizeof(buf
))
819 ok(!memcmp(buf
, emptyHashParam
, size
), "Unexpected value\n");
820 /* After updating the hash, further updates aren't allowed on streamed
823 SetLastError(0xdeadbeef);
824 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
825 ok(!ret
&& GetLastError() == NTE_BAD_HASH_STATE
,
826 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
830 static const BYTE hashEmptyBareContent
[] = {
831 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
832 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
833 static const BYTE hashEmptyContent
[] = {
834 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
835 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
836 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
837 static const BYTE hashBareContent
[] = {
838 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
839 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
840 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
841 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
842 static const BYTE hashContent
[] = {
843 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
844 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
845 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
846 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
847 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
849 static const BYTE detachedHashNonFinalBareContent
[] = {
850 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
851 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
852 0x07,0x01,0x04,0x00 };
853 static const BYTE detachedHashNonFinalContent
[] = {
854 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
855 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
856 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
857 0x07,0x01,0x04,0x00 };
858 static const BYTE detachedHashBareContent
[] = {
859 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
860 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
861 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
862 0x9d,0x2a,0x8f,0x26,0x2f };
863 static const BYTE detachedHashContent
[] = {
864 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
865 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
866 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
867 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
868 0x9d,0x2a,0x8f,0x26,0x2f };
870 static void test_hash_msg_encoding(void)
873 CMSG_HASHED_ENCODE_INFO hashInfo
= { sizeof(hashInfo
), 0 };
875 struct update_accum accum
= { 0, NULL
}, empty_accum
= { 0, NULL
};
876 CMSG_STREAM_INFO streamInfo
= { 0, accumulating_stream_output
, &accum
};
878 hashInfo
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
879 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
881 check_param("hash empty bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
882 hashEmptyBareContent
, sizeof(hashEmptyBareContent
));
883 check_param("hash empty content", msg
, CMSG_CONTENT_PARAM
,
884 hashEmptyContent
, sizeof(hashEmptyContent
));
885 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
886 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
887 check_param("hash bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
888 hashBareContent
, sizeof(hashBareContent
));
889 check_param("hash content", msg
, CMSG_CONTENT_PARAM
,
890 hashContent
, sizeof(hashContent
));
892 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
893 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_BARE_CONTENT_FLAG
,
894 CMSG_HASHED
, &hashInfo
, NULL
, NULL
);
895 check_param("hash empty bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
896 hashEmptyBareContent
, sizeof(hashEmptyBareContent
));
897 check_param("hash empty content", msg
, CMSG_CONTENT_PARAM
,
898 hashEmptyContent
, sizeof(hashEmptyContent
));
899 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
900 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
901 check_param("hash bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
902 hashBareContent
, sizeof(hashBareContent
));
903 check_param("hash content", msg
, CMSG_CONTENT_PARAM
,
904 hashContent
, sizeof(hashContent
));
906 /* Same test, but with CMSG_DETACHED_FLAG set */
907 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
908 CMSG_HASHED
, &hashInfo
, NULL
, NULL
);
909 check_param("detached hash empty bare content", msg
,
910 CMSG_BARE_CONTENT_PARAM
, hashEmptyBareContent
,
911 sizeof(hashEmptyBareContent
));
912 check_param("detached hash empty content", msg
, CMSG_CONTENT_PARAM
,
913 hashEmptyContent
, sizeof(hashEmptyContent
));
914 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
915 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
916 check_param("detached hash not final bare content", msg
,
917 CMSG_BARE_CONTENT_PARAM
, detachedHashNonFinalBareContent
,
918 sizeof(detachedHashNonFinalBareContent
));
919 check_param("detached hash not final content", msg
, CMSG_CONTENT_PARAM
,
920 detachedHashNonFinalContent
, sizeof(detachedHashNonFinalContent
));
921 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
922 ok(ret
, "CryptMsgUpdate failed: %08x\n", GetLastError());
923 check_param("detached hash bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
924 detachedHashBareContent
, sizeof(detachedHashBareContent
));
925 check_param("detached hash content", msg
, CMSG_CONTENT_PARAM
,
926 detachedHashContent
, sizeof(detachedHashContent
));
927 check_param("detached hash bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
928 detachedHashBareContent
, sizeof(detachedHashBareContent
));
929 check_param("detached hash content", msg
, CMSG_CONTENT_PARAM
,
930 detachedHashContent
, sizeof(detachedHashContent
));
932 /* In what appears to be a bug, streamed updates to hash messages don't
933 * call the output function.
935 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
937 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
938 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
939 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
940 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
942 check_updates("empty hash message", &empty_accum
, &accum
);
943 free_updates(&accum
);
945 streamInfo
.cbContent
= sizeof(msgData
);
946 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, &hashInfo
,
948 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
949 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
951 check_updates("hash message", &empty_accum
, &accum
);
952 free_updates(&accum
);
954 streamInfo
.cbContent
= sizeof(msgData
);
955 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, CMSG_DETACHED_FLAG
,
956 CMSG_HASHED
, &hashInfo
, NULL
, &streamInfo
);
957 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
958 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
960 check_updates("detached hash message", &empty_accum
, &accum
);
961 free_updates(&accum
);
964 static void test_hash_msg(void)
966 test_hash_msg_open();
967 test_hash_msg_update();
968 test_hash_msg_get_param();
969 test_hash_msg_encoding();
972 static const WCHAR cspNameW
[] = { 'W','i','n','e','C','r','y','p','t','T','e',
974 static BYTE serialNum
[] = { 1 };
975 static BYTE encodedCommonName
[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
976 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
978 static void test_signed_msg_open(void)
982 CMSG_SIGNED_ENCODE_INFO signInfo
= { 0 };
983 CMSG_SIGNER_ENCODE_INFO signer
= { sizeof(signer
), 0 };
984 CERT_INFO certInfo
= { 0 };
986 SetLastError(0xdeadbeef);
987 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
989 ok(!msg
&& GetLastError() == E_INVALIDARG
,
990 "Expected E_INVALIDARG, got %x\n", GetLastError());
991 signInfo
.cbSize
= sizeof(signInfo
);
992 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
994 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
997 signInfo
.cSigners
= 1;
998 signInfo
.rgSigners
= &signer
;
999 /* With signer.pCertInfo unset, attempting to open this message this
1002 signer
.pCertInfo
= &certInfo
;
1003 /* The cert info must contain a serial number and an issuer. */
1004 SetLastError(0xdeadbeef);
1005 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1007 ok(!msg
&& GetLastError() == E_INVALIDARG
,
1008 "Expected E_INVALIDARG, got %x\n", GetLastError());
1009 certInfo
.SerialNumber
.cbData
= sizeof(serialNum
);
1010 certInfo
.SerialNumber
.pbData
= serialNum
;
1011 SetLastError(0xdeadbeef);
1012 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1014 ok(!msg
&& GetLastError() == E_INVALIDARG
,
1015 "Expected E_INVALIDARG, got %x\n", GetLastError());
1016 certInfo
.Issuer
.cbData
= sizeof(encodedCommonName
);
1017 certInfo
.Issuer
.pbData
= encodedCommonName
;
1018 SetLastError(0xdeadbeef);
1019 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1021 ok(!msg
&& GetLastError() == E_INVALIDARG
,
1022 "Expected E_INVALIDARG, got %x\n", GetLastError());
1024 /* The signer's hCryptProv must be set to something. Whether it's usable
1025 * or not will be checked after the hash algorithm is checked (see next
1028 signer
.hCryptProv
= 1;
1029 SetLastError(0xdeadbeef);
1030 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1032 ok(!msg
&& GetLastError() == CRYPT_E_UNKNOWN_ALGO
,
1033 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1034 /* The signer's hash algorithm must also be set. */
1035 signer
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
1036 SetLastError(0xdeadbeef);
1037 /* Crashes in advapi32 in wine, don't do it */
1039 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
,
1040 &signInfo
, NULL
, NULL
);
1041 ok(!msg
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1042 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1044 /* The signer's hCryptProv must also be valid. */
1045 ret
= CryptAcquireContextW(&signer
.hCryptProv
, cspNameW
, NULL
,
1046 PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
1047 if (!ret
&& GetLastError() == NTE_EXISTS
)
1048 ret
= CryptAcquireContextW(&signer
.hCryptProv
, cspNameW
, NULL
,
1050 ok(ret
, "CryptAcquireContextW failed: %x\n", GetLastError());
1051 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1053 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1056 CryptReleaseContext(signer
.hCryptProv
, 0);
1057 CryptAcquireContextW(&signer
.hCryptProv
, cspNameW
, MS_DEF_PROV_W
,
1058 PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
1061 static const BYTE privKey
[] = {
1062 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1063 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1064 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1065 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1066 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1067 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1068 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1069 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1070 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1071 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1072 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1073 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1074 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1075 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1076 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1077 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1078 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1079 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1080 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1081 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1082 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1083 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1084 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1085 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1087 static void test_signed_msg_update(void)
1091 CMSG_SIGNED_ENCODE_INFO signInfo
= { sizeof(signInfo
), 0 };
1092 CMSG_SIGNER_ENCODE_INFO signer
= { sizeof(signer
), 0 };
1093 CERT_INFO certInfo
= { 0 };
1096 certInfo
.SerialNumber
.cbData
= sizeof(serialNum
);
1097 certInfo
.SerialNumber
.pbData
= serialNum
;
1098 certInfo
.Issuer
.cbData
= sizeof(encodedCommonName
);
1099 certInfo
.Issuer
.pbData
= encodedCommonName
;
1100 signer
.pCertInfo
= &certInfo
;
1101 signer
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
1102 signInfo
.cSigners
= 1;
1103 signInfo
.rgSigners
= &signer
;
1104 ret
= CryptAcquireContextW(&signer
.hCryptProv
, cspNameW
, NULL
,
1105 PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
1106 if (!ret
&& GetLastError() == NTE_EXISTS
)
1107 ret
= CryptAcquireContextW(&signer
.hCryptProv
, cspNameW
, NULL
,
1109 ok(ret
, "CryptAcquireContextW failed: %x\n", GetLastError());
1110 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
,
1111 CMSG_DETACHED_FLAG
, CMSG_SIGNED
, &signInfo
, NULL
, NULL
);
1112 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1113 /* Detached CMSG_SIGNED allows non-final updates. */
1114 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
1115 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1116 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1117 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
1118 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1119 /* The final update requires a private key in the hCryptProv, in order to
1120 * generate the signature.
1122 SetLastError(0xdeadbeef);
1123 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1124 ok(!ret
&& (GetLastError() == NTE_BAD_KEYSET
||
1125 GetLastError() == NTE_NO_KEY
),
1126 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1127 ret
= CryptImportKey(signer
.hCryptProv
, (LPBYTE
)privKey
, sizeof(privKey
),
1129 ok(ret
, "CryptImportKey failed: %08x\n", GetLastError());
1130 /* The final update should be able to succeed now that a key exists, but
1131 * the previous (invalid) final update prevents it.
1133 SetLastError(0xdeadbeef);
1134 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1135 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
1136 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1139 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
,
1140 CMSG_DETACHED_FLAG
, CMSG_SIGNED
, &signInfo
, NULL
, NULL
);
1141 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1142 /* Detached CMSG_SIGNED allows non-final updates. */
1143 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
1144 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1145 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1146 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
1147 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1148 /* Now that the private key exists, the final update can succeed (even
1151 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1152 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1153 /* But no updates are allowed after the final update. */
1154 SetLastError(0xdeadbeef);
1155 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
1156 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
1157 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1158 SetLastError(0xdeadbeef);
1159 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1160 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
1161 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1164 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1166 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1167 /* Non-detached messages don't allow non-final updates.. */
1168 SetLastError(0xdeadbeef);
1169 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
1170 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
1171 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1172 /* but they do allow final ones. */
1173 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1174 ok(ret
, "CryptMsgUpdate failed: %08x\n", GetLastError());
1176 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1178 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1179 /* They also allow final updates with no data. */
1180 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1181 ok(ret
, "CryptMsgUpdate failed: %08x\n", GetLastError());
1184 CryptDestroyKey(key
);
1185 CryptReleaseContext(signer
.hCryptProv
, 0);
1186 CryptAcquireContextW(&signer
.hCryptProv
, cspNameW
, NULL
, PROV_RSA_FULL
,
1187 CRYPT_DELETEKEYSET
);
1190 static const BYTE signedEmptyBareContent
[] = {
1191 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1192 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1193 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1194 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1195 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1196 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1197 static const BYTE signedEmptyContent
[] = {
1198 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1199 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1200 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1201 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1202 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1203 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1204 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1205 static const BYTE detachedSignedBareContent
[] = {
1206 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1207 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1208 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1209 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1210 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1211 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1212 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1213 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1214 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1215 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1216 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1217 static const BYTE detachedSignedContent
[] = {
1218 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1219 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1220 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1221 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1222 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1223 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1224 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1225 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1226 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1227 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1228 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1229 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1230 static const BYTE signedBareContent
[] = {
1231 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1232 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1233 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1234 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1235 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1236 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1237 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1238 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1239 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1240 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1241 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1242 static const BYTE signedContent
[] = {
1243 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1244 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1245 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1246 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1247 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1248 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1249 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1250 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1251 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1252 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1253 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1254 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1256 static const BYTE signedHash
[] = {
1257 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1259 static const BYTE signedEncodedSigner
[] = {
1260 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1261 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1262 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1263 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1264 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1265 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1266 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1267 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1268 static const BYTE signedWithAuthAttrsBareContent
[] = {
1269 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1270 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1271 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1272 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1273 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1274 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1275 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1276 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1277 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1278 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1279 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1280 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1281 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1282 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1283 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1284 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1285 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1286 0xff,0xc6,0x33,0x63,0x34 };
1287 static BYTE cert
[] = {
1288 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1289 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1290 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1291 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1292 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1293 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1294 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1295 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1296 0xff,0x02,0x01,0x01 };
1297 static const BYTE signedWithCertEmptyBareContent
[] = {
1298 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1299 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1300 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1301 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1302 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1303 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1304 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1305 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1306 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1307 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1308 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1309 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1310 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1311 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1312 static const BYTE signedWithCertBareContent
[] = {
1313 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1314 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1315 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1316 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1317 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1318 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1319 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1320 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1321 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1322 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1323 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1324 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1325 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1326 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1327 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1328 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1329 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1330 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1331 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1332 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1333 static BYTE crl
[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1334 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1335 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1336 0x30,0x30,0x30,0x30,0x5a };
1337 static const BYTE signedWithCrlEmptyBareContent
[] = {
1338 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1339 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1340 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1341 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1342 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1343 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1344 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1345 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1346 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1347 static const BYTE signedWithCrlBareContent
[] = {
1348 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1349 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1350 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1351 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1352 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1353 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1354 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1355 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1356 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1357 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1358 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1359 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1360 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1361 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1363 static const BYTE signedWithCertAndCrlEmptyBareContent
[] = {
1364 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1365 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1366 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1367 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1368 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1369 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1370 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1371 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1372 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1373 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1374 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1375 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1376 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1377 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1378 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1379 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1380 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1382 static const BYTE signedWithCertAndCrlBareContent
[] = {
1383 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1384 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1385 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1386 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1387 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1388 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1389 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1390 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1391 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1392 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1393 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1394 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1395 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1396 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1397 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1398 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1399 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1400 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1401 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1402 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1403 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1404 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1405 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1407 static void test_signed_msg_encoding(void)
1410 CMSG_SIGNED_ENCODE_INFO signInfo
= { sizeof(signInfo
), 0 };
1411 CMSG_SIGNER_ENCODE_INFO signer
= { sizeof(signer
), 0 };
1412 CERT_INFO certInfo
= { 0 };
1413 CERT_BLOB encodedCert
= { sizeof(cert
), cert
};
1414 CRL_BLOB encodedCrl
= { sizeof(crl
), crl
};
1415 char oid_common_name
[] = szOID_COMMON_NAME
;
1416 CRYPT_ATTR_BLOB commonName
= { sizeof(encodedCommonName
),
1417 encodedCommonName
};
1418 CRYPT_ATTRIBUTE attr
= { oid_common_name
, 1, &commonName
};
1423 certInfo
.SerialNumber
.cbData
= sizeof(serialNum
);
1424 certInfo
.SerialNumber
.pbData
= serialNum
;
1425 certInfo
.Issuer
.cbData
= sizeof(encodedCommonName
);
1426 certInfo
.Issuer
.pbData
= encodedCommonName
;
1427 signer
.pCertInfo
= &certInfo
;
1428 signer
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
1429 signInfo
.cSigners
= 1;
1430 signInfo
.rgSigners
= &signer
;
1431 ret
= CryptAcquireContextW(&signer
.hCryptProv
, cspNameW
, NULL
,
1432 PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
1433 if (!ret
&& GetLastError() == NTE_EXISTS
)
1434 ret
= CryptAcquireContextW(&signer
.hCryptProv
, cspNameW
, NULL
,
1436 ok(ret
, "CryptAcquireContextW failed: %x\n", GetLastError());
1437 ret
= CryptImportKey(signer
.hCryptProv
, (LPBYTE
)privKey
, sizeof(privKey
),
1439 ok(ret
, "CryptImportKey failed: %08x\n", GetLastError());
1441 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
,
1442 CMSG_DETACHED_FLAG
, CMSG_SIGNED
, &signInfo
, NULL
, NULL
);
1443 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1445 check_param("detached signed empty bare content", msg
,
1446 CMSG_BARE_CONTENT_PARAM
, signedEmptyBareContent
,
1447 sizeof(signedEmptyBareContent
));
1448 check_param("detached signed empty content", msg
, CMSG_CONTENT_PARAM
,
1449 signedEmptyContent
, sizeof(signedEmptyContent
));
1450 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1451 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1452 check_param("detached signed hash", msg
, CMSG_COMPUTED_HASH_PARAM
,
1453 signedHash
, sizeof(signedHash
));
1454 check_param("detached signed bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
1455 detachedSignedBareContent
, sizeof(detachedSignedBareContent
));
1456 check_param("detached signed content", msg
, CMSG_CONTENT_PARAM
,
1457 detachedSignedContent
, sizeof(detachedSignedContent
));
1458 SetLastError(0xdeadbeef);
1459 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 1, NULL
, &size
);
1460 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_INDEX
,
1461 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1462 check_param("detached signed encoded signer", msg
, CMSG_ENCODED_SIGNER
,
1463 signedEncodedSigner
, sizeof(signedEncodedSigner
));
1467 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1469 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1471 check_param("signed empty bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
1472 signedEmptyBareContent
, sizeof(signedEmptyBareContent
));
1473 check_param("signed empty content", msg
, CMSG_CONTENT_PARAM
,
1474 signedEmptyContent
, sizeof(signedEmptyContent
));
1475 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1476 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1477 check_param("signed bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
1478 signedBareContent
, sizeof(signedBareContent
));
1479 check_param("signed content", msg
, CMSG_CONTENT_PARAM
,
1480 signedContent
, sizeof(signedContent
));
1484 signer
.cAuthAttr
= 1;
1485 signer
.rgAuthAttr
= &attr
;
1486 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1488 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1490 CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1491 check_param("signed with auth attrs bare content", msg
,
1492 CMSG_BARE_CONTENT_PARAM
, signedWithAuthAttrsBareContent
,
1493 sizeof(signedWithAuthAttrsBareContent
));
1497 signer
.cAuthAttr
= 0;
1498 signInfo
.rgCertEncoded
= &encodedCert
;
1499 signInfo
.cCertEncoded
= 1;
1500 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1502 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1504 check_param("signed with cert empty bare content", msg
,
1505 CMSG_BARE_CONTENT_PARAM
, signedWithCertEmptyBareContent
,
1506 sizeof(signedWithCertEmptyBareContent
));
1507 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1508 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1509 check_param("signed with cert bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
1510 signedWithCertBareContent
, sizeof(signedWithCertBareContent
));
1514 signInfo
.cCertEncoded
= 0;
1515 signInfo
.rgCrlEncoded
= &encodedCrl
;
1516 signInfo
.cCrlEncoded
= 1;
1517 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1519 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1521 check_param("signed with crl empty bare content", msg
,
1522 CMSG_BARE_CONTENT_PARAM
, signedWithCrlEmptyBareContent
,
1523 sizeof(signedWithCrlEmptyBareContent
));
1524 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1525 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1526 check_param("signed with crl bare content", msg
, CMSG_BARE_CONTENT_PARAM
,
1527 signedWithCrlBareContent
, sizeof(signedWithCrlBareContent
));
1531 signInfo
.cCertEncoded
= 1;
1532 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1534 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1536 check_param("signed with cert and crl empty bare content", msg
,
1537 CMSG_BARE_CONTENT_PARAM
, signedWithCertAndCrlEmptyBareContent
,
1538 sizeof(signedWithCertAndCrlEmptyBareContent
));
1539 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1540 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1541 check_param("signed with cert and crl bare content", msg
,
1542 CMSG_BARE_CONTENT_PARAM
, signedWithCertAndCrlBareContent
,
1543 sizeof(signedWithCertAndCrlBareContent
));
1547 CryptDestroyKey(key
);
1548 CryptReleaseContext(signer
.hCryptProv
, 0);
1549 CryptAcquireContextW(&signer
.hCryptProv
, cspNameW
, NULL
, PROV_RSA_FULL
,
1550 CRYPT_DELETEKEYSET
);
1553 static void test_signed_msg_get_param(void)
1557 DWORD size
, value
= 0;
1558 CMSG_SIGNED_ENCODE_INFO signInfo
= { sizeof(signInfo
), 0 };
1559 CMSG_SIGNER_ENCODE_INFO signer
= { sizeof(signer
), 0 };
1560 CERT_INFO certInfo
= { 0 };
1562 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1564 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1566 /* Content and bare content are always gettable */
1568 ret
= CryptMsgGetParam(msg
, CMSG_CONTENT_PARAM
, 0, NULL
, &size
);
1569 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
1571 ret
= CryptMsgGetParam(msg
, CMSG_BARE_CONTENT_PARAM
, 0, NULL
, &size
);
1572 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
1573 /* For "signed" messages, so is the version. */
1575 ret
= CryptMsgGetParam(msg
, CMSG_VERSION_PARAM
, 0, NULL
, &size
);
1576 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
1577 size
= sizeof(value
);
1578 ret
= CryptMsgGetParam(msg
, CMSG_VERSION_PARAM
, 0, (LPBYTE
)&value
, &size
);
1579 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
1580 ok(value
== CMSG_SIGNED_DATA_V1
, "Expected version 1, got %d\n", value
);
1581 /* But for this message, with no signers, the hash and signer aren't
1585 SetLastError(0xdeadbeef);
1586 ret
= CryptMsgGetParam(msg
, CMSG_ENCODED_SIGNER
, 0, NULL
, &size
);
1587 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_INDEX
,
1588 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1589 SetLastError(0xdeadbeef);
1590 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, NULL
, &size
);
1591 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_INDEX
,
1592 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1593 /* As usual, the type isn't available. */
1594 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, NULL
, &size
);
1595 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
1596 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1600 certInfo
.SerialNumber
.cbData
= sizeof(serialNum
);
1601 certInfo
.SerialNumber
.pbData
= serialNum
;
1602 certInfo
.Issuer
.cbData
= sizeof(encodedCommonName
);
1603 certInfo
.Issuer
.pbData
= encodedCommonName
;
1604 signer
.pCertInfo
= &certInfo
;
1605 signer
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
1606 signInfo
.cSigners
= 1;
1607 signInfo
.rgSigners
= &signer
;
1608 ret
= CryptAcquireContextW(&signer
.hCryptProv
, cspNameW
, NULL
,
1609 PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
1610 if (!ret
&& GetLastError() == NTE_EXISTS
)
1611 ret
= CryptAcquireContextW(&signer
.hCryptProv
, cspNameW
, NULL
,
1613 ok(ret
, "CryptAcquireContextW failed: %x\n", GetLastError());
1614 msg
= CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, &signInfo
,
1616 ok(msg
!= NULL
, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1618 /* This message, with one signer, has the hash and signer for index 0
1619 * available, but not for other indexes.
1622 ret
= CryptMsgGetParam(msg
, CMSG_ENCODED_SIGNER
, 0, NULL
, &size
);
1623 ok(ret
, "CryptMsgGetParam failed: %x\n", GetLastError());
1624 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 0, NULL
, &size
);
1625 ok(ret
, "CryptMsgGetParam failed: %x\n", GetLastError());
1627 SetLastError(0xdeadbeef);
1628 ret
= CryptMsgGetParam(msg
, CMSG_ENCODED_SIGNER
, 1, NULL
, &size
);
1629 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_INDEX
,
1630 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1631 SetLastError(0xdeadbeef);
1632 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 1, NULL
, &size
);
1633 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_INDEX
,
1634 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1635 /* As usual, the type isn't available. */
1636 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, NULL
, &size
);
1637 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
1638 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1642 CryptReleaseContext(signer
.hCryptProv
, 0);
1643 CryptAcquireContextW(&signer
.hCryptProv
, cspNameW
, MS_DEF_PROV_W
,
1644 PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
1647 static void test_signed_msg(void)
1649 test_signed_msg_open();
1650 test_signed_msg_update();
1651 test_signed_msg_encoding();
1652 test_signed_msg_get_param();
1655 static CRYPT_DATA_BLOB b4
= { 0, NULL
};
1656 static const struct update_accum a4
= { 1, &b4
};
1658 static const BYTE bogusOIDContent
[] = {
1659 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1661 static const BYTE bogusHashContent
[] = {
1662 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1663 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1664 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1665 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1666 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1668 static void test_decode_msg_update(void)
1672 CMSG_STREAM_INFO streamInfo
= { 0 };
1674 struct update_accum accum
= { 0, NULL
};
1676 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1677 /* Update with a full message in a final update */
1678 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
), TRUE
);
1679 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1680 /* Can't update after a final update */
1681 SetLastError(0xdeadbeef);
1682 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
), TRUE
);
1683 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
1684 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1687 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1688 /* Can't send a non-final update without streaming */
1689 SetLastError(0xdeadbeef);
1690 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
),
1692 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
1693 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1694 /* A subsequent final update succeeds */
1695 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
), TRUE
);
1696 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1699 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, &streamInfo
);
1700 /* Updating a message that has a NULL stream callback fails */
1701 SetLastError(0xdeadbeef);
1702 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
),
1705 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
1706 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1707 /* Changing the callback pointer after the fact yields the same error (so
1708 * the message must copy the stream info, not just store a pointer to it)
1710 streamInfo
.pfnStreamOutput
= nop_stream_output
;
1711 SetLastError(0xdeadbeef);
1712 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
),
1715 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
1716 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1719 /* Empty non-final updates are allowed when streaming.. */
1720 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, &streamInfo
);
1721 ret
= CryptMsgUpdate(msg
, NULL
, 0, FALSE
);
1722 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1723 /* but final updates aren't when not enough data has been received. */
1724 SetLastError(0xdeadbeef);
1725 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1727 ok(!ret
&& GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA
,
1728 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1731 /* Updating the message byte by byte is legal */
1732 streamInfo
.pfnStreamOutput
= accumulating_stream_output
;
1733 streamInfo
.pvArg
= &accum
;
1734 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, &streamInfo
);
1735 for (i
= 0, ret
= TRUE
; ret
&& i
< sizeof(dataEmptyContent
); i
++)
1736 ret
= CryptMsgUpdate(msg
, &dataEmptyContent
[i
], 1, FALSE
);
1737 ok(ret
, "CryptMsgUpdate failed on byte %d: %x\n", i
, GetLastError());
1738 ret
= CryptMsgUpdate(msg
, NULL
, 0, TRUE
);
1739 ok(ret
, "CryptMsgUpdate failed on byte %d: %x\n", i
, GetLastError());
1742 check_updates("byte-by-byte empty content", &a4
, &accum
);
1743 free_updates(&accum
);
1745 /* Decoding bogus content fails in non-streaming mode.. */
1746 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1747 SetLastError(0xdeadbeef);
1748 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1749 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
1750 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1752 /* and as the final update in streaming mode.. */
1753 streamInfo
.pfnStreamOutput
= nop_stream_output
;
1754 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, &streamInfo
);
1755 SetLastError(0xdeadbeef);
1756 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), TRUE
);
1758 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
1759 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1761 /* and even as a non-final update in streaming mode. */
1762 streamInfo
.pfnStreamOutput
= nop_stream_output
;
1763 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, &streamInfo
);
1764 SetLastError(0xdeadbeef);
1765 ret
= CryptMsgUpdate(msg
, msgData
, sizeof(msgData
), FALSE
);
1767 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
1768 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1771 /* An empty message can be opened with indetermined type.. */
1772 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1773 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
),
1775 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1776 /* but decoding it as an explicitly typed message fails. */
1777 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, 0, NULL
,
1779 SetLastError(0xdeadbeef);
1780 ret
= CryptMsgUpdate(msg
, dataEmptyContent
, sizeof(dataEmptyContent
),
1782 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
1783 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1785 /* On the other hand, decoding the bare content of an empty message fails
1786 * with unspecified type..
1788 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1789 SetLastError(0xdeadbeef);
1790 ret
= CryptMsgUpdate(msg
, dataEmptyBareContent
,
1791 sizeof(dataEmptyBareContent
), TRUE
);
1792 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
1793 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1795 /* but succeeds with explicit type. */
1796 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_DATA
, 0, NULL
,
1798 ret
= CryptMsgUpdate(msg
, dataEmptyBareContent
,
1799 sizeof(dataEmptyBareContent
), TRUE
);
1800 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1803 /* Decoding valid content with an unsupported OID fails */
1804 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1805 SetLastError(0xdeadbeef);
1806 ret
= CryptMsgUpdate(msg
, bogusOIDContent
, sizeof(bogusOIDContent
), TRUE
);
1807 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
1808 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1811 /* Similarly, opening an empty hash with unspecified type succeeds.. */
1812 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1813 SetLastError(0xdeadbeef);
1814 ret
= CryptMsgUpdate(msg
, hashEmptyContent
, sizeof(hashEmptyContent
), TRUE
);
1815 ok(ret
, "CryptMsgUpdate failed: %08x\n", GetLastError());
1817 /* while with specified type it fails. */
1818 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
1820 SetLastError(0xdeadbeef);
1821 ret
= CryptMsgUpdate(msg
, hashEmptyContent
, sizeof(hashEmptyContent
), TRUE
);
1822 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
1823 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1825 /* On the other hand, decoding the bare content of an empty hash message
1826 * fails with unspecified type..
1828 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1829 SetLastError(0xdeadbeef);
1830 ret
= CryptMsgUpdate(msg
, hashEmptyBareContent
,
1831 sizeof(hashEmptyBareContent
), TRUE
);
1832 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
1833 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1835 /* but succeeds with explicit type. */
1836 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
1838 ret
= CryptMsgUpdate(msg
, hashEmptyBareContent
,
1839 sizeof(hashEmptyBareContent
), TRUE
);
1840 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1843 /* And again, opening a (non-empty) hash message with unspecified type
1846 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1847 SetLastError(0xdeadbeef);
1848 ret
= CryptMsgUpdate(msg
, hashContent
, sizeof(hashContent
), TRUE
);
1849 ok(ret
, "CryptMsgUpdate failed: %08x\n", GetLastError());
1851 /* while with specified type it fails.. */
1852 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
1854 SetLastError(0xdeadbeef);
1855 ret
= CryptMsgUpdate(msg
, hashContent
, sizeof(hashContent
), TRUE
);
1856 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
1857 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1859 /* and decoding the bare content of a non-empty hash message fails with
1860 * unspecified type..
1862 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1863 SetLastError(0xdeadbeef);
1864 ret
= CryptMsgUpdate(msg
, hashBareContent
, sizeof(hashBareContent
), TRUE
);
1865 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
1866 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1868 /* but succeeds with explicit type. */
1869 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_HASHED
, 0, NULL
,
1871 ret
= CryptMsgUpdate(msg
, hashBareContent
, sizeof(hashBareContent
), TRUE
);
1872 ok(ret
, "CryptMsgUpdate failed: %x\n", GetLastError());
1875 /* Opening a (non-empty) hash message with unspecified type and a bogus
1876 * hash value succeeds..
1878 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1879 SetLastError(0xdeadbeef);
1880 ret
= CryptMsgUpdate(msg
, bogusHashContent
, sizeof(bogusHashContent
), TRUE
);
1881 ok(ret
, "CryptMsgUpdate failed: %08x\n", GetLastError());
1884 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1885 ret
= CryptMsgUpdate(msg
, signedContent
, sizeof(signedContent
), TRUE
);
1886 ok(ret
, "CryptMsgUpdate failed: %08x\n", GetLastError());
1888 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1889 SetLastError(0xdeadbeef);
1890 ret
= CryptMsgUpdate(msg
, signedWithCertAndCrlBareContent
,
1891 sizeof(signedWithCertAndCrlBareContent
), TRUE
);
1892 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
1893 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1895 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, 0, NULL
,
1897 ret
= CryptMsgUpdate(msg
, signedWithCertAndCrlBareContent
,
1898 sizeof(signedWithCertAndCrlBareContent
), TRUE
);
1899 ok(ret
, "CryptMsgUpdate failed: %08x\n", GetLastError());
1903 static const BYTE hashParam
[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
1904 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1906 static void test_decode_msg_get_param(void)
1910 DWORD size
= 0, version
;
1913 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1914 SetLastError(0xdeadbeef);
1915 ret
= CryptMsgGetParam(msg
, CMSG_CONTENT_PARAM
, 0, NULL
, &size
);
1916 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
1917 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1918 ret
= CryptMsgUpdate(msg
, dataContent
, sizeof(dataContent
), TRUE
);
1919 check_param("data content", msg
, CMSG_CONTENT_PARAM
, msgData
,
1923 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1924 ret
= CryptMsgUpdate(msg
, hashEmptyContent
, sizeof(hashEmptyContent
), TRUE
);
1925 check_param("empty hash content", msg
, CMSG_CONTENT_PARAM
, NULL
, 0);
1926 check_param("empty hash hash data", msg
, CMSG_HASH_DATA_PARAM
, NULL
, 0);
1927 check_param("empty hash computed hash", msg
, CMSG_COMPUTED_HASH_PARAM
,
1928 emptyHashParam
, sizeof(emptyHashParam
));
1930 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
1931 ret
= CryptMsgUpdate(msg
, hashContent
, sizeof(hashContent
), TRUE
);
1932 check_param("hash content", msg
, CMSG_CONTENT_PARAM
, msgData
,
1934 check_param("hash hash data", msg
, CMSG_HASH_DATA_PARAM
, hashParam
,
1936 check_param("hash computed hash", msg
, CMSG_COMPUTED_HASH_PARAM
,
1937 hashParam
, sizeof(hashParam
));
1938 /* Curiously, getting the hash of index 1 succeeds, even though there's
1941 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 1, NULL
, &size
);
1942 ok(ret
, "CryptMsgGetParam failed: %08x\n", GetLastError());
1943 buf
= CryptMemAlloc(size
);
1946 ret
= CryptMsgGetParam(msg
, CMSG_COMPUTED_HASH_PARAM
, 1, buf
, &size
);
1947 ok(size
== sizeof(hashParam
), "Unexpected size %d\n", size
);
1948 ok(!memcmp(buf
, hashParam
, size
), "Unexpected value\n");
1951 check_param("hash inner OID", msg
, CMSG_INNER_CONTENT_TYPE_PARAM
,
1952 (const BYTE
*)szOID_RSA_data
, strlen(szOID_RSA_data
) + 1);
1953 version
= CMSG_HASHED_DATA_V0
;
1954 check_param("hash version", msg
, CMSG_VERSION_PARAM
, (const BYTE
*)&version
,
1959 static void test_decode_msg(void)
1961 test_decode_msg_update();
1962 test_decode_msg_get_param();
1967 /* Basic parameter checking tests */
1968 test_msg_open_to_encode();
1969 test_msg_open_to_decode();
1970 test_msg_get_param();
1973 /* Message-type specific tests */