dinput: Clear DIA_APPNOMAP BuildActionMap flag with specific device semantic.
[wine.git] / dlls / crypt32 / tests / msg.c
blob16f7402c61329c0a98efce2c8f263431180a39f6
1 /*
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
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winerror.h>
26 #define CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS
27 #define CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS
28 #include <wincrypt.h>
30 #include "wine/test.h"
32 static char oid_rsa_md5[] = szOID_RSA_MD5;
34 static void test_msg_open_to_encode(void)
36 HCRYPTMSG msg;
38 /* Crash
39 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
40 NULL, NULL);
41 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
42 NULL);
43 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
44 NULL);
47 /* Bad encodings */
48 SetLastError(0xdeadbeef);
49 msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
50 ok(!msg && GetLastError() == E_INVALIDARG,
51 "Expected E_INVALIDARG, got %lx\n", GetLastError());
52 SetLastError(0xdeadbeef);
53 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
54 ok(!msg && GetLastError() == E_INVALIDARG,
55 "Expected E_INVALIDARG, got %lx\n", GetLastError());
57 /* Bad message types */
58 SetLastError(0xdeadbeef);
59 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
60 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
61 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
62 SetLastError(0xdeadbeef);
63 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
64 NULL, NULL, NULL);
65 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
66 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
67 SetLastError(0xdeadbeef);
68 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
69 CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
70 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
71 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
72 SetLastError(0xdeadbeef);
73 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
74 NULL, NULL);
75 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
76 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
79 static void test_msg_open_to_decode(void)
81 HCRYPTMSG msg;
82 CMSG_STREAM_INFO streamInfo = { 0 };
84 SetLastError(0xdeadbeef);
85 msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
86 ok(!msg && GetLastError() == E_INVALIDARG,
87 "Expected E_INVALIDARG, got %lx\n", GetLastError());
89 /* Bad encodings */
90 SetLastError(0xdeadbeef);
91 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
92 ok(!msg && GetLastError() == E_INVALIDARG,
93 "Expected E_INVALIDARG, got %lx\n", GetLastError());
94 SetLastError(0xdeadbeef);
95 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
96 ok(!msg && GetLastError() == E_INVALIDARG,
97 "Expected E_INVALIDARG, got %lx\n", GetLastError());
99 /* The message type can be explicit... */
100 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
101 NULL);
102 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
103 CryptMsgClose(msg);
104 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
105 NULL);
106 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
107 CryptMsgClose(msg);
108 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
109 NULL);
110 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
111 CryptMsgClose(msg);
112 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
113 NULL);
114 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
115 CryptMsgClose(msg);
116 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
117 CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
118 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
119 CryptMsgClose(msg);
120 /* or implicit.. */
121 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
122 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
123 CryptMsgClose(msg);
124 /* or even invalid. */
125 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
126 NULL);
127 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
128 CryptMsgClose(msg);
129 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
130 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
131 CryptMsgClose(msg);
133 /* And even though the stream info parameter "must be set to NULL" for
134 * CMSG_HASHED, it's still accepted.
136 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
137 &streamInfo);
138 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
139 CryptMsgClose(msg);
142 static void test_msg_get_param(void)
144 BOOL ret;
145 HCRYPTMSG msg;
146 DWORD size, i, value;
148 /* Crash
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: %lx\n", GetLastError());
157 /* For decoded messages, the type is always available */
158 size = 0;
159 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
160 ok(ret, "CryptMsgGetParam failed: %lx\n", GetLastError());
161 size = sizeof(value);
162 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
163 ok(ret, "CryptMsgGetParam failed: %lx\n", GetLastError());
164 /* For this (empty) message, the type isn't set */
165 ok(value == 0, "Expected type 0, got %ld\n", value);
166 CryptMsgClose(msg);
168 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
169 NULL);
170 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
171 /* For explicitly typed messages, the type is known. */
172 size = sizeof(value);
173 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
174 ok(ret, "CryptMsgGetParam failed: %lx\n", GetLastError());
175 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %ld\n", value);
176 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
178 size = 0;
179 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
180 ok(!ret, "Parameter %ld: expected failure\n", i);
182 CryptMsgClose(msg);
184 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
185 NULL);
186 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
187 size = sizeof(value);
188 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
189 ok(ret, "CryptMsgGetParam failed: %lx\n", GetLastError());
190 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %ld\n", value);
191 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
193 size = 0;
194 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
195 ok(!ret, "Parameter %ld: expected failure\n", i);
197 CryptMsgClose(msg);
199 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
200 NULL);
201 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
202 size = sizeof(value);
203 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
204 ok(ret, "CryptMsgGetParam failed: %lx\n", GetLastError());
205 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %ld\n", value);
206 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
208 size = 0;
209 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
210 ok(!ret, "Parameter %ld: expected failure\n", i);
212 CryptMsgClose(msg);
214 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
215 NULL);
216 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
217 size = sizeof(value);
218 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
219 ok(ret, "CryptMsgGetParam failed: %lx\n", GetLastError());
220 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %ld\n", value);
221 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
223 size = 0;
224 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
225 ok(!ret, "Parameter %ld: expected failure\n", i);
227 CryptMsgClose(msg);
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,
231 NULL);
232 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
233 size = sizeof(value);
234 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
235 ok(ret, "CryptMsgGetParam failed: %lx\n", GetLastError());
236 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %ld\n", value);
237 CryptMsgClose(msg);
239 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
240 ok(msg != NULL, "CryptMsgOpenToDecode failed: %lx\n", GetLastError());
241 size = sizeof(value);
242 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
243 ok(ret, "CryptMsgGetParam failed: %lx\n", GetLastError());
244 ok(value == 1000, "Expected 1000, got %ld\n", value);
245 CryptMsgClose(msg);
248 static void test_msg_close(void)
250 BOOL ret;
251 HCRYPTMSG msg;
253 /* NULL succeeds.. */
254 ret = CryptMsgClose(NULL);
255 ok(ret, "CryptMsgClose failed: %lx\n", GetLastError());
256 /* but an arbitrary pointer crashes. */
257 if (0)
258 ret = CryptMsgClose((HCRYPTMSG)1);
259 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
260 NULL);
261 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
262 ret = CryptMsgClose(msg);
263 ok(ret, "CryptMsgClose failed: %lx\n", GetLastError());
266 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
267 const BYTE *expected, DWORD expectedSize)
269 DWORD size;
270 LPBYTE buf;
271 BOOL ret;
273 size = 0xdeadbeef;
274 ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
275 ok(ret, "%s: CryptMsgGetParam failed: %08lx\n", test, GetLastError());
277 buf = malloc(size);
278 ret = CryptMsgGetParam(msg, param, 0, buf, &size);
279 ok(ret, "%s: CryptMsgGetParam failed: %08lx\n", test, GetLastError());
280 ok(size == expectedSize, "%s: expected size %ld, got %ld\n", test,
281 expectedSize, size);
282 if (size == expectedSize && size)
283 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
284 free(buf);
287 static void test_data_msg_open(void)
289 HCRYPTMSG msg;
290 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
291 CMSG_STREAM_INFO streamInfo = { 0 };
292 char oid[] = "1.2.3";
294 /* The data message type takes no additional info */
295 SetLastError(0xdeadbeef);
296 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
297 NULL, NULL);
298 ok(!msg && GetLastError() == E_INVALIDARG,
299 "Expected E_INVALIDARG, got %lx\n", GetLastError());
300 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
301 NULL);
302 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
303 CryptMsgClose(msg);
305 /* An empty stream info is allowed. */
306 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
307 &streamInfo);
308 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
309 CryptMsgClose(msg);
311 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
312 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
313 NULL);
314 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
315 CryptMsgClose(msg);
316 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
317 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
318 CMSG_DATA, NULL, oid, NULL);
319 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
320 CryptMsgClose(msg);
321 /* and when a stream info is given, even though you're not supposed to be
322 * able to use anything but szOID_RSA_data when streaming is being used.
324 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
325 CMSG_DATA, NULL, oid, &streamInfo);
326 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
327 CryptMsgClose(msg);
330 static const BYTE msgData[] = { 1, 2, 3, 4 };
332 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
333 BOOL final)
335 return TRUE;
338 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
340 static void test_data_msg_update(void)
342 HCRYPTMSG msg;
343 BOOL ret;
344 CMSG_STREAM_INFO streamInfo = { 0 };
346 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
347 NULL);
348 /* Can't update a message that wasn't opened detached with final = FALSE */
349 SetLastError(0xdeadbeef);
350 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
351 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
352 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
353 /* Updating it with final = TRUE succeeds */
354 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
355 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
356 /* Any subsequent update will fail, as the last was final */
357 SetLastError(0xdeadbeef);
358 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
359 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
360 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
361 CryptMsgClose(msg);
363 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
364 NULL);
365 /* Starting with Vista, can update a message with no data. */
366 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
367 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
368 if (ret)
370 DWORD size;
372 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
373 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
374 if (ret)
376 LPBYTE buf = CryptMemAlloc(size);
378 if (buf)
380 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, buf,
381 &size);
382 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
383 if (ret)
385 ok(size == sizeof(dataEmptyBareContent),
386 "unexpected size %ld\n", size);
387 ok(!memcmp(buf, dataEmptyBareContent, size),
388 "unexpected value\n");
390 CryptMemFree(buf);
394 CryptMsgClose(msg);
396 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
397 CMSG_DATA, NULL, NULL, NULL);
399 SetLastError(0xdeadbeef);
400 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
401 ok(!ret && GetLastError() == E_INVALIDARG,
402 "Expected E_INVALIDARG, got %lx\n", GetLastError());
403 SetLastError(0xdeadbeef);
404 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
405 ok(!ret && GetLastError() == E_INVALIDARG,
406 "Expected E_INVALIDARG, got %lx\n", GetLastError());
408 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
409 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
410 CryptMsgClose(msg);
412 /* Calling update after opening with an empty stream info (with a bogus
413 * output function) yields an error:
415 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
416 &streamInfo);
417 SetLastError(0xdeadbeef);
418 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
419 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
420 "Expected STATUS_ACCESS_VIOLATION, got %lx\n", GetLastError());
421 CryptMsgClose(msg);
423 /* Calling update with a valid output function succeeds, even if the data
424 * exceeds the size specified in the stream info.
426 streamInfo.pfnStreamOutput = nop_stream_output;
427 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
428 &streamInfo);
429 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
430 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
431 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
432 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
433 CryptMsgClose(msg);
436 static void test_data_msg_get_param(void)
438 HCRYPTMSG msg;
439 DWORD size;
440 BOOL ret;
441 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
443 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
444 NULL);
446 /* Content and bare content are always gettable when not streaming */
447 size = 0;
448 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
449 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
450 size = 0;
451 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
452 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
453 /* But for this type of message, the signer and hash aren't applicable,
454 * and the type isn't available.
456 size = 0;
457 SetLastError(0xdeadbeef);
458 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
459 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
460 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
461 SetLastError(0xdeadbeef);
462 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
463 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
464 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
465 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
466 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
467 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
468 CryptMsgClose(msg);
470 /* Can't get content or bare content when streaming */
471 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
472 NULL, &streamInfo);
473 SetLastError(0xdeadbeef);
474 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
475 ok(!ret && GetLastError() == E_INVALIDARG,
476 "Expected E_INVALIDARG, got %lx\n", GetLastError());
477 SetLastError(0xdeadbeef);
478 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
479 ok(!ret && GetLastError() == E_INVALIDARG,
480 "Expected E_INVALIDARG, got %lx\n", GetLastError());
481 CryptMsgClose(msg);
484 static const BYTE dataEmptyContent[] = {
485 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
486 0x04,0x00 };
487 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
488 static const BYTE dataContent[] = {
489 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
490 0x04,0x04,0x01,0x02,0x03,0x04 };
492 struct update_accum
494 DWORD cUpdates;
495 CRYPT_DATA_BLOB *updates;
498 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
499 DWORD cb, BOOL final)
501 struct update_accum *accum = (struct update_accum *)pvArg;
502 BOOL ret = FALSE;
504 if (accum->cUpdates)
505 accum->updates = CryptMemRealloc(accum->updates,
506 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
507 else
508 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
509 if (accum->updates)
511 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
513 blob->pbData = CryptMemAlloc(cb);
514 if (blob->pbData)
516 memcpy(blob->pbData, pb, cb);
517 blob->cbData = cb;
518 ret = TRUE;
520 accum->cUpdates++;
522 return ret;
525 /* The updates of a (bogus) definite-length encoded message */
526 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
527 0x07,0x01,0xa0,0x02,0x04,0x00 };
528 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
529 static CRYPT_DATA_BLOB b1[] = {
530 { sizeof(u1), u1 },
531 { sizeof(u2), u2 },
532 { sizeof(u2), u2 },
534 static const struct update_accum a1 = { ARRAY_SIZE(b1), b1 };
535 /* The updates of a definite-length encoded message */
536 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
537 0x07,0x01,0xa0,0x06,0x04,0x04 };
538 static CRYPT_DATA_BLOB b2[] = {
539 { sizeof(u3), u3 },
540 { sizeof(u2), u2 },
542 static const struct update_accum a2 = { ARRAY_SIZE(b2), b2 };
543 /* The updates of an indefinite-length encoded message */
544 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
545 0x07,0x01,0xa0,0x80,0x24,0x80 };
546 static BYTE u5[] = { 0x04,0x04 };
547 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
548 static CRYPT_DATA_BLOB b3[] = {
549 { sizeof(u4), u4 },
550 { sizeof(u5), u5 },
551 { sizeof(u2), u2 },
552 { sizeof(u5), u5 },
553 { sizeof(u2), u2 },
554 { sizeof(u6), u6 },
556 static const struct update_accum a3 = { ARRAY_SIZE(b3), b3 };
558 static void check_updates(LPCSTR header, const struct update_accum *expected,
559 const struct update_accum *got)
561 DWORD i;
563 ok(expected->cUpdates == got->cUpdates,
564 "%s: expected %ld updates, got %ld\n", header, expected->cUpdates,
565 got->cUpdates);
566 if (expected->cUpdates == got->cUpdates)
567 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
569 ok(expected->updates[i].cbData == got->updates[i].cbData,
570 "%s, update %ld: expected %ld bytes, got %ld\n", header, i,
571 expected->updates[i].cbData, got->updates[i].cbData);
572 if (expected->updates[i].cbData && expected->updates[i].cbData ==
573 got->updates[i].cbData)
574 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
575 got->updates[i].cbData), "%s, update %ld: unexpected value\n",
576 header, i);
580 /* Frees the updates stored in accum */
581 static void free_updates(struct update_accum *accum)
583 DWORD i;
585 for (i = 0; i < accum->cUpdates; i++)
586 CryptMemFree(accum->updates[i].pbData);
587 CryptMemFree(accum->updates);
588 accum->updates = NULL;
589 accum->cUpdates = 0;
592 static void test_data_msg_encoding(void)
594 HCRYPTMSG msg;
595 BOOL ret;
596 static char oid[] = "1.2.3";
597 struct update_accum accum = { 0, NULL };
598 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
600 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
601 NULL);
602 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
603 dataEmptyBareContent, sizeof(dataEmptyBareContent));
604 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
605 sizeof(dataEmptyContent));
606 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
607 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
608 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
609 dataBareContent, sizeof(dataBareContent));
610 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
611 sizeof(dataContent));
612 CryptMsgClose(msg);
613 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
614 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
615 CMSG_DATA, NULL, NULL, NULL);
616 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
617 dataEmptyBareContent, sizeof(dataEmptyBareContent));
618 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
619 sizeof(dataEmptyContent));
620 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
621 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
622 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
623 dataBareContent, sizeof(dataBareContent));
624 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
625 sizeof(dataContent));
626 CryptMsgClose(msg);
627 /* The inner OID is apparently ignored */
628 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
629 NULL);
630 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
631 dataEmptyBareContent, sizeof(dataEmptyBareContent));
632 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
633 dataEmptyContent, sizeof(dataEmptyContent));
634 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
635 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
636 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
637 dataBareContent, sizeof(dataBareContent));
638 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
639 sizeof(dataContent));
640 CryptMsgClose(msg);
641 /* A streaming message is DER encoded if the length is not 0xffffffff, but
642 * curiously, updates aren't validated to make sure they don't exceed the
643 * stated length. (The resulting output will of course fail to decode.)
645 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
646 NULL, &streamInfo);
647 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
648 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
649 CryptMsgClose(msg);
650 check_updates("bogus data message with definite length", &a1, &accum);
651 free_updates(&accum);
652 /* A valid definite-length encoding: */
653 streamInfo.cbContent = sizeof(msgData);
654 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
655 NULL, &streamInfo);
656 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
657 CryptMsgClose(msg);
658 check_updates("data message with definite length", &a2, &accum);
659 free_updates(&accum);
660 /* An indefinite-length encoding: */
661 streamInfo.cbContent = 0xffffffff;
662 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
663 NULL, &streamInfo);
664 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
665 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
666 CryptMsgClose(msg);
667 check_updates("data message with indefinite length", &a3, &accum);
668 free_updates(&accum);
671 static void test_data_msg(void)
673 test_data_msg_open();
674 test_data_msg_update();
675 test_data_msg_get_param();
676 test_data_msg_encoding();
679 static void test_hash_msg_open(void)
681 HCRYPTMSG msg;
682 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
683 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
685 SetLastError(0xdeadbeef);
686 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
687 NULL, NULL);
688 ok(!msg && GetLastError() == E_INVALIDARG,
689 "Expected E_INVALIDARG, got %lx\n", GetLastError());
690 hashInfo.cbSize = sizeof(hashInfo);
691 SetLastError(0xdeadbeef);
692 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
693 NULL, NULL);
694 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
695 "Expected CRYPT_E_UNKNOWN_ALGO, got %lx\n", GetLastError());
696 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
697 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
698 NULL, NULL);
699 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
700 CryptMsgClose(msg);
701 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
702 CMSG_HASHED, &hashInfo, NULL, NULL);
703 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
704 CryptMsgClose(msg);
705 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
706 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
707 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
708 CryptMsgClose(msg);
711 static void test_hash_msg_update(void)
713 HCRYPTMSG msg;
714 BOOL ret;
715 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
716 { oid_rsa_md5, { 0, NULL } }, NULL };
717 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
719 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
720 CMSG_HASHED, &hashInfo, NULL, NULL);
721 /* Detached hashed messages opened in non-streaming mode allow non-final
722 * updates..
724 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
725 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
726 /* including non-final updates with no data.. */
727 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
728 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
729 /* and final updates with no data. */
730 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
731 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
732 /* But no updates are allowed after the final update. */
733 SetLastError(0xdeadbeef);
734 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
735 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
736 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
737 SetLastError(0xdeadbeef);
738 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
739 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
740 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
741 CryptMsgClose(msg);
742 /* Non-detached messages, in contrast, don't allow non-final updates in
743 * non-streaming mode.
745 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
746 NULL, NULL);
747 SetLastError(0xdeadbeef);
748 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
749 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
750 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
751 /* Final updates (including empty ones) are allowed. */
752 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
753 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
754 CryptMsgClose(msg);
755 /* And, of course, streaming mode allows non-final updates */
756 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
757 NULL, &streamInfo);
758 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
759 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
760 CryptMsgClose(msg);
761 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
762 * to be a bug, it isn't actually used - see encoding tests.)
764 streamInfo.pfnStreamOutput = NULL;
765 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
766 NULL, &streamInfo);
767 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
768 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
769 CryptMsgClose(msg);
772 static const BYTE emptyHashParam[] = {
773 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
774 0x7e };
776 static void test_hash_msg_get_param(void)
778 HCRYPTMSG msg;
779 BOOL ret;
780 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
781 { oid_rsa_md5, { 0, NULL } }, NULL };
782 DWORD size, value;
783 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
784 BYTE buf[16];
786 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
787 NULL, NULL);
788 /* Content and bare content are always gettable for non-streamed messages */
789 size = 0;
790 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
791 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
792 size = 0;
793 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
794 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
795 /* For an encoded hash message, the hash data aren't available */
796 SetLastError(0xdeadbeef);
797 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
798 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
799 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n",
800 GetLastError());
801 /* The hash is also available. */
802 size = 0;
803 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
804 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
805 ok(size == sizeof(buf), "Unexpected size %ld\n", size);
806 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
807 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
808 ok(size == sizeof(buf), "Unexpected size %ld\n", size);
809 if (size == sizeof(buf))
810 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
811 /* By getting the hash, further updates are not allowed */
812 SetLastError(0xdeadbeef);
813 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
814 ok(!ret && (GetLastError() == NTE_BAD_HASH_STATE || GetLastError() == CRYPT_E_MSG_ERROR),
815 "Expected CRYPT_E_MSG_ERROR, got 0x%lx\n", GetLastError());
817 /* Even after a final update, the hash data aren't available */
818 SetLastError(0xdeadbeef);
819 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
820 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
821 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
822 /* The version is also available, and should be zero for this message. */
823 size = 0;
824 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
825 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
826 size = sizeof(value);
827 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
828 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
829 if (ret)
830 ok(value == 0, "Expected version 0, got %ld\n", value);
831 /* As usual, the type isn't available. */
832 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
833 ok(!ret, "Expected failure\n");
834 CryptMsgClose(msg);
836 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
837 NULL, &streamInfo);
838 /* Streamed messages don't allow you to get the content or bare content. */
839 SetLastError(0xdeadbeef);
840 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
841 ok(!ret && GetLastError() == E_INVALIDARG,
842 "Expected E_INVALIDARG, got %lx\n", GetLastError());
843 SetLastError(0xdeadbeef);
844 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
845 ok(!ret && GetLastError() == E_INVALIDARG,
846 "Expected E_INVALIDARG, got %lx\n", GetLastError());
847 /* The hash is still available. */
848 size = 0;
849 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
850 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
851 ok(size == sizeof(buf), "Unexpected size %ld\n", size);
852 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
853 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
854 if (size == sizeof(buf))
855 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
856 /* After updating the hash, further updates aren't allowed on streamed
857 * messages either.
859 SetLastError(0xdeadbeef);
860 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
861 ok(!ret && (GetLastError() == NTE_BAD_HASH_STATE || GetLastError() == CRYPT_E_MSG_ERROR),
862 "Expected CRYPT_E_MSG_ERROR, got 0x%lx\n", GetLastError());
864 CryptMsgClose(msg);
867 static const BYTE hashEmptyBareContent[] = {
868 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
869 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
870 static const BYTE hashEmptyContent[] = {
871 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
872 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
873 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
874 static const BYTE hashBareContent[] = {
875 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
876 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
877 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
878 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
879 static const BYTE hashContent[] = {
880 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
881 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
882 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
883 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
884 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
886 static const BYTE detachedHashNonFinalBareContent[] = {
887 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
888 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
889 0x07,0x01,0x04,0x00 };
890 static const BYTE detachedHashNonFinalContent[] = {
891 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
892 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
893 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
894 0x07,0x01,0x04,0x00 };
895 static const BYTE detachedHashBareContent[] = {
896 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
897 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
898 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
899 0x9d,0x2a,0x8f,0x26,0x2f };
900 static const BYTE detachedHashContent[] = {
901 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
902 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
903 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
904 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
905 0x9d,0x2a,0x8f,0x26,0x2f };
907 static void test_hash_msg_encoding(void)
909 HCRYPTMSG msg;
910 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
911 BOOL ret;
912 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
913 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
915 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
916 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
917 NULL, NULL);
918 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
919 hashEmptyBareContent, sizeof(hashEmptyBareContent));
920 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
921 hashEmptyContent, sizeof(hashEmptyContent));
922 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
923 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
924 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
925 hashBareContent, sizeof(hashBareContent));
926 check_param("hash content", msg, CMSG_CONTENT_PARAM,
927 hashContent, sizeof(hashContent));
928 CryptMsgClose(msg);
929 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
930 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
931 CMSG_HASHED, &hashInfo, NULL, NULL);
932 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
933 hashEmptyBareContent, sizeof(hashEmptyBareContent));
934 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
935 hashEmptyContent, sizeof(hashEmptyContent));
936 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
937 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
938 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
939 hashBareContent, sizeof(hashBareContent));
940 check_param("hash content", msg, CMSG_CONTENT_PARAM,
941 hashContent, sizeof(hashContent));
942 CryptMsgClose(msg);
943 /* Same test, but with CMSG_DETACHED_FLAG set */
944 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
945 CMSG_HASHED, &hashInfo, NULL, NULL);
946 check_param("detached hash empty bare content", msg,
947 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
948 sizeof(hashEmptyBareContent));
949 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
950 hashEmptyContent, sizeof(hashEmptyContent));
951 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
952 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
953 check_param("detached hash not final bare content", msg,
954 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
955 sizeof(detachedHashNonFinalBareContent));
956 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
957 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
958 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
959 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
960 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
961 detachedHashBareContent, sizeof(detachedHashBareContent));
962 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
963 detachedHashContent, sizeof(detachedHashContent));
964 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
965 detachedHashBareContent, sizeof(detachedHashBareContent));
966 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
967 detachedHashContent, sizeof(detachedHashContent));
968 CryptMsgClose(msg);
969 /* In what appears to be a bug, streamed updates to hash messages don't
970 * call the output function.
972 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
973 NULL, &streamInfo);
974 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
975 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
976 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
977 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
978 CryptMsgClose(msg);
979 check_updates("empty hash message", &empty_accum, &accum);
980 free_updates(&accum);
982 streamInfo.cbContent = sizeof(msgData);
983 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
984 NULL, &streamInfo);
985 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
986 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
987 CryptMsgClose(msg);
988 check_updates("hash message", &empty_accum, &accum);
989 free_updates(&accum);
991 streamInfo.cbContent = sizeof(msgData);
992 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
993 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
994 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
995 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
996 CryptMsgClose(msg);
997 check_updates("detached hash message", &empty_accum, &accum);
998 free_updates(&accum);
1001 static void test_hash_msg(void)
1003 test_hash_msg_open();
1004 test_hash_msg_update();
1005 test_hash_msg_get_param();
1006 test_hash_msg_encoding();
1009 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1010 'm','p',0 };
1011 static BYTE serialNum[] = { 1 };
1012 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1013 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1015 static void test_signed_msg_open(void)
1017 HCRYPTMSG msg;
1018 BOOL ret;
1019 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1020 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1021 CERT_INFO certInfo = { 0 };
1023 SetLastError(0xdeadbeef);
1024 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1025 NULL, NULL);
1026 ok(!msg && GetLastError() == E_INVALIDARG,
1027 "Expected E_INVALIDARG, got %lx\n", GetLastError());
1028 signInfo.cbSize = sizeof(signInfo);
1029 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1030 NULL, NULL);
1031 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1032 CryptMsgClose(msg);
1034 signInfo.cSigners = 1;
1035 signInfo.rgSigners = &signer;
1036 /* With signer.pCertInfo unset, attempting to open this message this
1037 * crashes.
1039 signer.pCertInfo = &certInfo;
1040 /* The cert info must contain a serial number and an issuer. */
1041 SetLastError(0xdeadbeef);
1042 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1043 NULL, NULL);
1044 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1045 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1046 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1047 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%lx\n",
1048 GetLastError());
1050 certInfo.SerialNumber.cbData = sizeof(serialNum);
1051 certInfo.SerialNumber.pbData = serialNum;
1052 SetLastError(0xdeadbeef);
1053 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1054 NULL, NULL);
1055 ok(!msg && GetLastError() == E_INVALIDARG,
1056 "Expected E_INVALIDARG, got 0x%lx\n", GetLastError());
1058 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1059 certInfo.Issuer.pbData = encodedCommonName;
1060 SetLastError(0xdeadbeef);
1061 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1062 NULL, NULL);
1063 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1064 "Expected E_INVALIDARG or CRYPT_E_UNKNOWN_ALGO, got %lx\n", GetLastError());
1066 /* The signer's hCryptProv must be set to something. Whether it's usable
1067 * or not will be checked after the hash algorithm is checked (see next
1068 * test.)
1070 signer.hCryptProv = 1;
1071 SetLastError(0xdeadbeef);
1072 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1073 NULL, NULL);
1074 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1075 "Expected CRYPT_E_UNKNOWN_ALGO, got %lx\n", GetLastError());
1076 /* The signer's hash algorithm must also be set. */
1077 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1078 SetLastError(0xdeadbeef);
1079 /* Crashes in advapi32 in wine, don't do it */
1080 if (0) {
1081 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1082 &signInfo, NULL, NULL);
1083 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1084 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1086 /* The signer's hCryptProv must also be valid. */
1087 ret = CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1088 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1089 if (!ret && GetLastError() == NTE_EXISTS) {
1090 ret = CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1091 PROV_RSA_FULL, 0);
1093 ok(ret, "CryptAcquireContext failed: 0x%lx\n", GetLastError());
1095 if (ret) {
1096 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1097 NULL, NULL);
1098 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1099 CryptMsgClose(msg);
1102 /* pCertInfo must still be set, but can be empty if the SignerId's issuer
1103 * and serial number are set.
1105 certInfo.Issuer.cbData = 0;
1106 certInfo.SerialNumber.cbData = 0;
1107 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1108 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1109 sizeof(encodedCommonName);
1110 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1111 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1112 sizeof(serialNum);
1113 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1114 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1115 NULL, NULL);
1116 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1117 CryptMsgClose(msg);
1119 CryptReleaseContext(signer.hCryptProv, 0);
1120 CryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1121 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1124 static const BYTE privKey[] = {
1125 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1126 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1127 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1128 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1129 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1130 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1131 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1132 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1133 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1134 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1135 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1136 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1137 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1138 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1139 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1140 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1141 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1142 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1143 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1144 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1145 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1146 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1147 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1148 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1149 static BYTE pubKey[] = {
1150 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1151 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1152 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1153 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1154 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1156 static void test_signed_msg_update(void)
1158 HCRYPTMSG msg;
1159 BOOL ret;
1160 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1161 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1162 CERT_INFO certInfo = { 0 };
1163 HCRYPTKEY key;
1165 certInfo.SerialNumber.cbData = sizeof(serialNum);
1166 certInfo.SerialNumber.pbData = serialNum;
1167 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1168 certInfo.Issuer.pbData = encodedCommonName;
1169 signer.pCertInfo = &certInfo;
1170 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1171 signInfo.cSigners = 1;
1172 signInfo.rgSigners = &signer;
1174 ret = CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1175 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1176 if (!ret && GetLastError() == NTE_EXISTS) {
1177 ret = CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1178 PROV_RSA_FULL, 0);
1180 ok(ret, "CryptAcquireContext failed: 0x%lx\n", GetLastError());
1182 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1183 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1184 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1185 /* Detached CMSG_SIGNED allows non-final updates. */
1186 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1187 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
1188 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1189 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1190 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
1191 /* The final update requires a private key in the hCryptProv, in order to
1192 * generate the signature.
1194 SetLastError(0xdeadbeef);
1195 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1196 ok(!ret && (GetLastError() == NTE_BAD_KEYSET || GetLastError() == NTE_NO_KEY),
1197 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %lx\n", GetLastError());
1198 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1199 0, 0, &key);
1200 ok(ret, "CryptImportKey failed: %08lx\n", GetLastError());
1201 /* The final update should be able to succeed now that a key exists, but
1202 * the previous (invalid) final update prevents it.
1204 SetLastError(0xdeadbeef);
1205 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1206 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1207 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
1208 CryptMsgClose(msg);
1210 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1211 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1212 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1213 /* Detached CMSG_SIGNED allows non-final updates. */
1214 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1215 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
1216 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1217 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1218 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
1219 /* Now that the private key exists, the final update can succeed (even
1220 * with no data.)
1222 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1223 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
1224 /* But no updates are allowed after the final update. */
1225 SetLastError(0xdeadbeef);
1226 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1227 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1228 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
1229 SetLastError(0xdeadbeef);
1230 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1231 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1232 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
1233 CryptMsgClose(msg);
1235 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1236 NULL, NULL);
1237 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1238 /* Non-detached messages don't allow non-final updates.. */
1239 SetLastError(0xdeadbeef);
1240 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1241 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1242 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
1243 /* but they do allow final ones. */
1244 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1245 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
1246 CryptMsgClose(msg);
1247 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1248 NULL, NULL);
1249 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1250 /* They also allow final updates with no data. */
1251 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1252 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
1253 CryptMsgClose(msg);
1255 CryptDestroyKey(key);
1256 CryptReleaseContext(signer.hCryptProv, 0);
1257 CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1258 CRYPT_DELETEKEYSET);
1261 static const BYTE signedEmptyBareContent[] = {
1262 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1263 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1264 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1265 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1266 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1267 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1268 static const BYTE signedEmptyContent[] = {
1269 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1270 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1271 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1272 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1273 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1274 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1275 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1276 static const BYTE detachedSignedBareContent[] = {
1277 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1278 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1279 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1280 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1281 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1282 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1283 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1284 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1285 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1286 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1287 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1288 static const BYTE detachedSignedContent[] = {
1289 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1290 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1291 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1292 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1293 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1294 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1295 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1296 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1297 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1298 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1299 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1300 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1301 static const BYTE signedBareContent[] = {
1302 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1303 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1304 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1305 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1306 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1307 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1308 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1309 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1310 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1311 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1312 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1313 static const BYTE signedContent[] = {
1314 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1315 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1316 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1317 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1318 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1319 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1320 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1321 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1322 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1323 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1324 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1325 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1326 0x0d };
1327 static const BYTE signedHash[] = {
1328 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1329 0x2f };
1330 static const BYTE signedKeyIdEmptyContent[] = {
1331 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
1332 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1333 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
1334 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1335 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1336 static const BYTE signedEncodedSigner[] = {
1337 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1338 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1339 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1340 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1341 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1342 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1343 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1344 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1345 static const BYTE signedWithAuthAttrsBareContent[] = {
1346 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1347 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1348 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1349 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1350 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1351 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1352 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1353 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1354 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1355 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1356 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1357 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1358 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1359 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1360 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1361 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1362 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1363 0xff,0xc6,0x33,0x63,0x34 };
1364 static BYTE cert[] = {
1365 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1366 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1367 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1368 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1369 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1370 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1371 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1372 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1373 0xff,0x02,0x01,0x01 };
1374 static BYTE v1CertWithPubKey[] = {
1375 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1376 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1377 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1378 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1379 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1380 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1381 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1382 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1383 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1384 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1385 0x01,0x01 };
1386 static const BYTE signedWithCertEmptyBareContent[] = {
1387 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1388 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1389 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1390 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1391 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1392 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1393 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1394 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1395 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1396 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1397 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1398 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1399 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1400 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1401 static const BYTE signedWithCertBareContent[] = {
1402 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1403 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1404 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1405 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1406 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1407 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1408 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1409 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1410 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1411 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1412 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1413 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1414 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1415 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1416 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1417 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1418 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1419 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1420 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1421 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1422 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1423 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1424 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1425 0x30,0x30,0x30,0x30,0x5a };
1426 static const BYTE signedWithCrlEmptyBareContent[] = {
1427 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1428 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1429 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1430 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1431 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1432 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1433 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1434 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1435 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1436 static const BYTE signedWithCrlBareContent[] = {
1437 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1438 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1439 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1440 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1441 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1442 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1443 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1444 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1445 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1446 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1447 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1448 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1449 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1450 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1451 0xa8,0x0d };
1452 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1453 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1454 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1455 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1456 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1457 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1458 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1459 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1460 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1461 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1462 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1463 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1464 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1465 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1466 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1467 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1468 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1469 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1470 0x04,0x00 };
1471 static const BYTE signedWithCertAndCrlBareContent[] = {
1472 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1473 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1474 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1475 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1476 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1477 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1478 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1479 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1480 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1481 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1482 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1483 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1484 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1485 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1486 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1487 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1488 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1489 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1490 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1491 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1492 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1493 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1494 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1495 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1496 0x30,0x81,0xeb,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,0x81,0x98,0x30,
1498 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1499 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1500 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1501 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1502 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1503 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1504 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1505 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1506 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1507 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1508 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1509 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1510 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1511 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1512 static BYTE v1CertWithValidPubKey[] = {
1513 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1514 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1515 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1516 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1517 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1518 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1519 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1520 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1521 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1522 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1523 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1524 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1525 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1526 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1527 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1528 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1529 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1530 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1531 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1532 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1533 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1534 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1535 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1536 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1537 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1538 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1539 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1540 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1541 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1542 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1543 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1544 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1545 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1546 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1547 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1548 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1549 0x00 };
1550 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1551 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1552 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1553 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1554 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1555 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1556 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1557 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1558 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1559 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1560 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1561 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1562 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1563 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1564 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1565 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1566 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1567 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1568 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1569 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1570 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1571 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1572 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1573 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1574 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1575 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1576 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1577 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1579 static void test_signed_msg_encoding(void)
1581 HCRYPTMSG msg;
1582 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1583 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1584 CERT_INFO certInfo = { 0 };
1585 CERT_BLOB encodedCert = { sizeof(cert), cert };
1586 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1587 char oid_common_name[] = szOID_COMMON_NAME;
1588 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1589 encodedCommonName };
1590 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1591 BOOL ret;
1592 HCRYPTKEY key;
1593 DWORD size;
1595 certInfo.SerialNumber.cbData = sizeof(serialNum);
1596 certInfo.SerialNumber.pbData = serialNum;
1597 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1598 certInfo.Issuer.pbData = encodedCommonName;
1599 signer.pCertInfo = &certInfo;
1600 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1601 signInfo.cSigners = 1;
1602 signInfo.rgSigners = &signer;
1604 ret = CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1605 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1606 if (!ret && GetLastError() == NTE_EXISTS) {
1607 ret = CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1608 PROV_RSA_FULL, 0);
1610 ok(ret, "CryptAcquireContext failed: 0x%lx\n", GetLastError());
1612 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1613 0, 0, &key);
1614 ok(ret, "CryptImportKey failed: %08lx\n", GetLastError());
1616 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1617 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1618 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1620 check_param("detached signed empty bare content", msg,
1621 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1622 sizeof(signedEmptyBareContent));
1623 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1624 signedEmptyContent, sizeof(signedEmptyContent));
1625 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1626 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
1627 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1628 signedHash, sizeof(signedHash));
1629 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1630 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1631 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1632 detachedSignedContent, sizeof(detachedSignedContent));
1633 SetLastError(0xdeadbeef);
1634 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1635 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1636 "Expected CRYPT_E_INVALID_INDEX, got %lx\n", GetLastError());
1637 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1638 signedEncodedSigner, sizeof(signedEncodedSigner));
1640 CryptMsgClose(msg);
1642 certInfo.SerialNumber.cbData = 0;
1643 certInfo.Issuer.cbData = 0;
1644 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1645 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1646 U(signer.SignerId).KeyId.pbData = serialNum;
1647 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1648 NULL, NULL);
1649 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1650 check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM,
1651 signedKeyIdEmptyContent, sizeof(signedKeyIdEmptyContent));
1652 CryptMsgClose(msg);
1654 certInfo.SerialNumber.cbData = sizeof(serialNum);
1655 certInfo.SerialNumber.pbData = serialNum;
1656 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1657 certInfo.Issuer.pbData = encodedCommonName;
1658 signer.SignerId.dwIdChoice = 0;
1659 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1660 NULL, NULL);
1661 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1663 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1664 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1665 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1666 signedEmptyContent, sizeof(signedEmptyContent));
1667 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1668 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
1669 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1670 signedBareContent, sizeof(signedBareContent));
1671 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1672 signedContent, sizeof(signedContent));
1674 CryptMsgClose(msg);
1676 signer.cAuthAttr = 1;
1677 signer.rgAuthAttr = &attr;
1678 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1679 NULL, NULL);
1680 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1682 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1683 check_param("signed with auth attrs bare content", msg,
1684 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1685 sizeof(signedWithAuthAttrsBareContent));
1687 CryptMsgClose(msg);
1689 signer.cAuthAttr = 0;
1690 signInfo.rgCertEncoded = &encodedCert;
1691 signInfo.cCertEncoded = 1;
1692 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1693 NULL, NULL);
1694 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1696 check_param("signed with cert empty bare content", msg,
1697 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1698 sizeof(signedWithCertEmptyBareContent));
1699 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1700 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
1701 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1702 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1704 CryptMsgClose(msg);
1706 signInfo.cCertEncoded = 0;
1707 signInfo.rgCrlEncoded = &encodedCrl;
1708 signInfo.cCrlEncoded = 1;
1709 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1710 NULL, NULL);
1711 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1713 check_param("signed with crl empty bare content", msg,
1714 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1715 sizeof(signedWithCrlEmptyBareContent));
1716 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1717 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
1718 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1719 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1721 CryptMsgClose(msg);
1723 signInfo.cCertEncoded = 1;
1724 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1725 NULL, NULL);
1726 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1728 check_param("signed with cert and crl empty bare content", msg,
1729 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1730 sizeof(signedWithCertAndCrlEmptyBareContent));
1731 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1732 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
1733 check_param("signed with cert and crl bare content", msg,
1734 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1735 sizeof(signedWithCertAndCrlBareContent));
1737 CryptMsgClose(msg);
1739 /* Test with a cert with a (bogus) public key */
1740 signInfo.cCrlEncoded = 0;
1741 encodedCert.cbData = sizeof(v1CertWithPubKey);
1742 encodedCert.pbData = v1CertWithPubKey;
1743 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1744 NULL, NULL);
1745 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1746 check_param("signedWithCertWithPubKeyBareContent", msg,
1747 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1748 sizeof(signedWithCertWithPubKeyBareContent));
1749 CryptMsgClose(msg);
1751 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1752 encodedCert.pbData = v1CertWithValidPubKey;
1753 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1754 NULL, NULL);
1755 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1756 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1757 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1758 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1759 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1760 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
1761 check_param("signedWithCertWithValidPubKeyContent", msg,
1762 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1763 sizeof(signedWithCertWithValidPubKeyContent));
1764 CryptMsgClose(msg);
1766 CryptDestroyKey(key);
1767 CryptReleaseContext(signer.hCryptProv, 0);
1768 CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1769 CRYPT_DELETEKEYSET);
1772 static void test_signed_msg_get_param(void)
1774 BOOL ret;
1775 HCRYPTMSG msg;
1776 DWORD size, value = 0;
1777 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1778 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1779 CERT_INFO certInfo = { 0 };
1781 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1782 NULL, NULL);
1783 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1785 /* Content and bare content are always gettable */
1786 size = 0;
1787 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1788 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1790 size = 0;
1791 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1792 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1793 /* For "signed" messages, so is the version. */
1794 size = 0;
1795 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1796 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1797 size = sizeof(value);
1798 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1799 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1800 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %ld\n", value);
1801 /* But for this message, with no signers, the hash and signer aren't
1802 * available.
1804 size = 0;
1805 SetLastError(0xdeadbeef);
1806 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1807 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1808 "Expected CRYPT_E_INVALID_INDEX, got %lx\n", GetLastError());
1809 SetLastError(0xdeadbeef);
1810 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1811 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1812 "Expected CRYPT_E_INVALID_INDEX, got %lx\n", GetLastError());
1813 /* As usual, the type isn't available. */
1814 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1815 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1816 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
1818 CryptMsgClose(msg);
1820 certInfo.SerialNumber.cbData = sizeof(serialNum);
1821 certInfo.SerialNumber.pbData = serialNum;
1822 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1823 certInfo.Issuer.pbData = encodedCommonName;
1824 signer.pCertInfo = &certInfo;
1825 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1826 signInfo.cSigners = 1;
1827 signInfo.rgSigners = &signer;
1829 ret = CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1830 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1831 if (!ret && GetLastError() == NTE_EXISTS) {
1832 ret = CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1833 PROV_RSA_FULL, 0);
1835 ok(ret, "CryptAcquireContext failed: 0x%lx\n", GetLastError());
1837 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1838 NULL, NULL);
1839 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1841 /* This message, with one signer, has the hash and signer for index 0
1842 * available, but not for other indexes.
1844 size = 0;
1845 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1846 ok(ret, "CryptMsgGetParam failed: %lx\n", GetLastError());
1847 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1848 ok(ret, "CryptMsgGetParam failed: %lx\n", GetLastError());
1849 size = 0;
1850 SetLastError(0xdeadbeef);
1851 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1852 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1853 "Expected CRYPT_E_INVALID_INDEX, got %lx\n", GetLastError());
1854 SetLastError(0xdeadbeef);
1855 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1856 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1857 "Expected CRYPT_E_INVALID_INDEX, got %lx\n", GetLastError());
1858 /* As usual, the type isn't available. */
1859 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1860 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1861 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
1863 CryptMsgClose(msg);
1865 /* Opening the message using the CMS fields.. */
1866 certInfo.SerialNumber.cbData = 0;
1867 certInfo.Issuer.cbData = 0;
1868 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1869 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1870 sizeof(encodedCommonName);
1871 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1872 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1873 sizeof(serialNum);
1874 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1875 ret = CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1876 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1877 if (!ret && GetLastError() == NTE_EXISTS)
1878 ret = CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1879 PROV_RSA_FULL, 0);
1880 ok(ret, "CryptAcquireContextA failed: %lx\n", GetLastError());
1881 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1882 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1883 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1884 /* still results in the version being 1 when the issuer and serial number
1885 * are used and no additional CMS fields are used.
1887 size = sizeof(value);
1888 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1889 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1890 if (ret)
1891 ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %ld\n", value);
1892 /* Apparently the encoded signer can be retrieved.. */
1893 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1894 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1895 /* but the signer info, CMS signer info, and cert ID can't be. */
1896 SetLastError(0xdeadbeef);
1897 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1898 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1899 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
1900 SetLastError(0xdeadbeef);
1901 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1902 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1903 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
1904 SetLastError(0xdeadbeef);
1905 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1906 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1907 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
1908 CryptMsgClose(msg);
1910 /* Using the KeyId field of the SignerId results in the version becoming
1911 * the CMS version.
1913 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1914 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1915 U(signer.SignerId).KeyId.pbData = serialNum;
1916 ret = CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1917 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1918 if (!ret && GetLastError() == NTE_EXISTS)
1919 ret = CryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1920 PROV_RSA_FULL, 0);
1921 ok(ret, "CryptAcquireContextA failed: %lx\n", GetLastError());
1922 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1923 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1924 ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
1925 size = sizeof(value);
1926 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1927 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1928 if (ret)
1929 ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %ld\n", value);
1930 /* Even for a CMS message, the signer can be retrieved.. */
1931 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1932 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
1933 /* but the signer info, CMS signer info, and cert ID can't be. */
1934 SetLastError(0xdeadbeef);
1935 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1936 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1937 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
1938 SetLastError(0xdeadbeef);
1939 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1940 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1941 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
1942 SetLastError(0xdeadbeef);
1943 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1944 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1945 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
1946 CryptMsgClose(msg);
1948 CryptReleaseContext(signer.hCryptProv, 0);
1949 CryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1950 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1953 static void test_signed_msg(void)
1955 test_signed_msg_open();
1956 test_signed_msg_update();
1957 test_signed_msg_encoding();
1958 test_signed_msg_get_param();
1961 static char oid_rsa_rc4[] = szOID_RSA_RC4;
1963 static void test_enveloped_msg_open(void)
1965 HCRYPTMSG msg;
1966 BOOL ret;
1967 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { 0 };
1968 PCCERT_CONTEXT context;
1970 SetLastError(0xdeadbeef);
1971 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
1972 &envelopedInfo, NULL, NULL);
1973 ok(!msg && GetLastError() == E_INVALIDARG,
1974 "expected E_INVALIDARG, got %08lx\n", GetLastError());
1976 envelopedInfo.cbSize = sizeof(envelopedInfo);
1977 SetLastError(0xdeadbeef);
1978 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
1979 &envelopedInfo, NULL, NULL);
1980 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1981 "expected CRYPT_E_UNKNOWN_ALGO, got %08lx\n", GetLastError());
1983 envelopedInfo.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4;
1984 SetLastError(0xdeadbeef);
1985 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
1986 &envelopedInfo, NULL, NULL);
1987 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
1988 CryptMsgClose(msg);
1990 envelopedInfo.cRecipients = 1;
1991 SetLastError(0xdeadbeef);
1992 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
1993 &envelopedInfo, NULL, NULL);
1994 ok(!msg && GetLastError() == E_INVALIDARG,
1995 "expected E_INVALIDARG, got %08lx\n", GetLastError());
1997 context = CertCreateCertificateContext(X509_ASN_ENCODING,
1998 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
2000 envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo;
2001 SetLastError(0xdeadbeef);
2002 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2003 &envelopedInfo, NULL, NULL);
2004 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2005 CryptMsgClose(msg);
2006 SetLastError(0xdeadbeef);
2007 ret = CryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL,
2008 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
2009 ok(ret, "CryptAcquireContextA failed: %08lx\n", GetLastError());
2010 SetLastError(0xdeadbeef);
2011 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2012 &envelopedInfo, NULL, NULL);
2013 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2014 CryptMsgClose(msg);
2015 CryptReleaseContext(envelopedInfo.hCryptProv, 0);
2016 CertFreeCertificateContext(context);
2019 static void test_enveloped_msg_update(void)
2021 HCRYPTMSG msg;
2022 BOOL ret;
2023 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2024 { oid_rsa_rc4, { 0, NULL } }, NULL };
2025 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
2027 SetLastError(0xdeadbeef);
2028 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2029 &envelopedInfo, NULL, NULL);
2030 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2032 SetLastError(0xdeadbeef);
2033 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2034 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2035 "expected CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
2036 SetLastError(0xdeadbeef);
2037 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2038 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2039 SetLastError(0xdeadbeef);
2040 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2041 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2042 "expected CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
2043 CryptMsgClose(msg);
2045 SetLastError(0xdeadbeef);
2046 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2047 &envelopedInfo, NULL, NULL);
2048 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2050 SetLastError(0xdeadbeef);
2051 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2052 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2053 "expected CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
2054 SetLastError(0xdeadbeef);
2055 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2056 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2057 SetLastError(0xdeadbeef);
2058 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2059 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2060 "expected CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
2061 CryptMsgClose(msg);
2063 SetLastError(0xdeadbeef);
2064 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2065 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2066 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2068 SetLastError(0xdeadbeef);
2069 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2070 ok(!ret && GetLastError() == E_INVALIDARG,
2071 "expected E_INVALIDARG, got %08lx\n", GetLastError());
2072 SetLastError(0xdeadbeef);
2073 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2074 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2075 CryptMsgClose(msg);
2077 SetLastError(0xdeadbeef);
2078 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2079 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2080 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2082 SetLastError(0xdeadbeef);
2083 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2084 ok(!ret && GetLastError() == E_INVALIDARG,
2085 "expected E_INVALIDARG, got %08lx\n", GetLastError());
2086 SetLastError(0xdeadbeef);
2087 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2088 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2089 CryptMsgClose(msg);
2091 SetLastError(0xdeadbeef);
2092 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2093 &envelopedInfo, NULL, &streamInfo);
2094 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2096 SetLastError(0xdeadbeef);
2097 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2098 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2099 SetLastError(0xdeadbeef);
2100 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2101 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2102 CryptMsgClose(msg);
2104 SetLastError(0xdeadbeef);
2105 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2106 &envelopedInfo, NULL, &streamInfo);
2107 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2109 SetLastError(0xdeadbeef);
2110 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2111 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2112 SetLastError(0xdeadbeef);
2113 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2114 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2115 CryptMsgClose(msg);
2118 static const BYTE envelopedEmptyBareContent[] = {
2119 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2120 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2121 0x03,0x04,0x05,0x00,0x80,0x00 };
2122 static const BYTE envelopedEmptyContent[] = {
2123 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24,
2124 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2125 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2126 0x03,0x04,0x05,0x00,0x80,0x00 };
2128 static void test_enveloped_msg_encoding(void)
2130 HCRYPTMSG msg;
2131 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2132 { oid_rsa_rc4, { 0, NULL } }, NULL };
2134 SetLastError(0xdeadbeef);
2135 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2136 &envelopedInfo, NULL, NULL);
2137 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08lx\n", GetLastError());
2138 check_param("enveloped empty bare content", msg,
2139 CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent,
2140 sizeof(envelopedEmptyBareContent));
2141 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
2142 envelopedEmptyContent, sizeof(envelopedEmptyContent));
2143 CryptMsgClose(msg);
2146 static void test_enveloped_msg(void)
2148 test_enveloped_msg_open();
2149 test_enveloped_msg_update();
2150 test_enveloped_msg_encoding();
2153 static CRYPT_DATA_BLOB b4 = { 0, NULL };
2154 static const struct update_accum a4 = { 1, &b4 };
2156 static const BYTE bogusOIDContent[] = {
2157 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2158 0x04,0x00 };
2159 static const BYTE bogusHashContent[] = {
2160 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2161 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2162 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2163 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2164 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2165 static const BYTE envelopedBareContentWithoutData[] = {
2166 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2167 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2168 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2169 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2170 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b,
2171 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f,
2172 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94,
2173 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72,
2174 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18,
2175 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3,
2176 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6,
2177 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49,
2178 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e,
2179 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2180 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 };
2182 static void test_decode_msg_update(void)
2184 HCRYPTMSG msg;
2185 BOOL ret;
2186 CMSG_STREAM_INFO streamInfo = { 0 };
2187 DWORD i;
2188 struct update_accum accum = { 0, NULL };
2190 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2191 /* Update with a full message in a final update */
2192 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2193 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
2194 /* Can't update after a final update */
2195 SetLastError(0xdeadbeef);
2196 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2197 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2198 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
2199 CryptMsgClose(msg);
2201 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2202 /* Can't send a non-final update without streaming */
2203 SetLastError(0xdeadbeef);
2204 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2205 FALSE);
2206 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2207 "Expected CRYPT_E_MSG_ERROR, got %lx\n", GetLastError());
2208 /* A subsequent final update succeeds */
2209 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2210 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
2211 CryptMsgClose(msg);
2213 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2214 /* Updating a message that has a NULL stream callback fails */
2215 SetLastError(0xdeadbeef);
2216 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), FALSE);
2217 todo_wine
2218 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2219 "Expected STATUS_ACCESS_VIOLATION, got %lx\n", GetLastError());
2220 /* Changing the callback pointer after the fact yields the same error (so
2221 * the message must copy the stream info, not just store a pointer to it)
2223 streamInfo.pfnStreamOutput = nop_stream_output;
2224 SetLastError(0xdeadbeef);
2225 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), FALSE);
2226 todo_wine
2227 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2228 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %lx\n", GetLastError());
2229 CryptMsgClose(msg);
2231 /* Empty non-final updates are allowed when streaming.. */
2232 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2233 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2234 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
2235 /* but final updates aren't when not enough data has been received. */
2236 SetLastError(0xdeadbeef);
2237 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2238 todo_wine
2239 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2240 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %lx\n", GetLastError());
2241 CryptMsgClose(msg);
2243 /* Updating the message byte by byte is legal */
2244 streamInfo.pfnStreamOutput = accumulating_stream_output;
2245 streamInfo.pvArg = &accum;
2246 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2247 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2248 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2249 ok(ret, "CryptMsgUpdate failed on byte %ld: %lx\n", i, GetLastError());
2250 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2251 ok(ret, "CryptMsgUpdate failed on byte %ld: %lx\n", i, GetLastError());
2252 CryptMsgClose(msg);
2253 todo_wine
2254 check_updates("byte-by-byte empty content", &a4, &accum);
2255 free_updates(&accum);
2257 /* Decoding bogus content fails in non-streaming mode.. */
2258 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2259 SetLastError(0xdeadbeef);
2260 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2261 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2262 "Expected CRYPT_E_ASN1_BADTAG, got %lx\n",
2263 GetLastError());
2264 CryptMsgClose(msg);
2265 /* and as the final update in streaming mode.. */
2266 streamInfo.pfnStreamOutput = nop_stream_output;
2267 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2268 SetLastError(0xdeadbeef);
2269 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2270 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2271 "Expected CRYPT_E_ASN1_BADTAG, got %lx\n",
2272 GetLastError());
2273 CryptMsgClose(msg);
2274 /* and even as a non-final update in streaming mode. */
2275 streamInfo.pfnStreamOutput = nop_stream_output;
2276 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2277 SetLastError(0xdeadbeef);
2278 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2279 todo_wine
2280 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2281 "Expected CRYPT_E_ASN1_BADTAG, got %lx\n", GetLastError());
2282 CryptMsgClose(msg);
2284 /* An empty message can be opened with undetermined type.. */
2285 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2286 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2287 TRUE);
2288 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
2289 CryptMsgClose(msg);
2290 /* but decoding it as an explicitly typed message fails. */
2291 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2292 NULL);
2293 SetLastError(0xdeadbeef);
2294 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2295 TRUE);
2296 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2297 "Expected CRYPT_E_ASN1_BADTAG, got %lx\n", GetLastError());
2298 CryptMsgClose(msg);
2299 /* On the other hand, decoding the bare content of an empty message fails
2300 * with unspecified type..
2302 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2303 SetLastError(0xdeadbeef);
2304 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2305 sizeof(dataEmptyBareContent), TRUE);
2306 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2307 "Expected CRYPT_E_ASN1_BADTAG, got %lx\n", GetLastError());
2308 CryptMsgClose(msg);
2309 /* but succeeds with explicit type. */
2310 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2311 NULL);
2312 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2313 sizeof(dataEmptyBareContent), TRUE);
2314 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
2315 CryptMsgClose(msg);
2317 /* Decoding valid content with an unsupported OID fails */
2318 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2319 SetLastError(0xdeadbeef);
2320 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2321 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2322 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
2323 CryptMsgClose(msg);
2325 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2326 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2327 SetLastError(0xdeadbeef);
2328 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2329 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2330 CryptMsgClose(msg);
2331 /* while with specified type it fails. */
2332 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2333 NULL);
2334 SetLastError(0xdeadbeef);
2335 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2336 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2337 "Expected CRYPT_E_ASN1_BADTAG, got %lx\n", GetLastError());
2338 CryptMsgClose(msg);
2339 /* On the other hand, decoding the bare content of an empty hash message
2340 * fails with unspecified type..
2342 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2343 SetLastError(0xdeadbeef);
2344 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2345 sizeof(hashEmptyBareContent), TRUE);
2346 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2347 "Expected CRYPT_E_ASN1_BADTAG, got %lx\n", GetLastError());
2348 CryptMsgClose(msg);
2349 /* but succeeds with explicit type. */
2350 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2351 NULL);
2352 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2353 sizeof(hashEmptyBareContent), TRUE);
2354 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
2355 CryptMsgClose(msg);
2357 /* And again, opening a (non-empty) hash message with unspecified type
2358 * succeeds..
2360 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2361 SetLastError(0xdeadbeef);
2362 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2363 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2364 CryptMsgClose(msg);
2365 /* while with specified type it fails.. */
2366 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2367 NULL);
2368 SetLastError(0xdeadbeef);
2369 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2370 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2371 "Expected CRYPT_E_ASN1_BADTAG, got %lx\n", GetLastError());
2372 CryptMsgClose(msg);
2373 /* and decoding the bare content of a non-empty hash message fails with
2374 * unspecified type..
2376 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2377 SetLastError(0xdeadbeef);
2378 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2379 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2380 "Expected CRYPT_E_ASN1_BADTAG, got %lx\n",
2381 GetLastError());
2382 CryptMsgClose(msg);
2383 /* but succeeds with explicit type. */
2384 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2385 NULL);
2386 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2387 ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
2388 CryptMsgClose(msg);
2390 /* Opening a (non-empty) hash message with unspecified type and a bogus
2391 * hash value succeeds..
2393 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2394 SetLastError(0xdeadbeef);
2395 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2396 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2397 CryptMsgClose(msg);
2399 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2400 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2401 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2402 CryptMsgClose(msg);
2403 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2404 SetLastError(0xdeadbeef);
2405 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2406 sizeof(signedWithCertAndCrlBareContent), TRUE);
2407 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2408 "Expected CRYPT_E_ASN1_BADTAG, got %08lx\n", GetLastError());
2409 CryptMsgClose(msg);
2410 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2411 NULL);
2412 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2413 sizeof(signedWithCertAndCrlBareContent), TRUE);
2414 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2415 CryptMsgClose(msg);
2417 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2418 NULL, NULL);
2419 /* The first update succeeds.. */
2420 ret = CryptMsgUpdate(msg, detachedSignedContent,
2421 sizeof(detachedSignedContent), TRUE);
2422 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2423 /* as does a second (probably to update the detached portion).. */
2424 ret = CryptMsgUpdate(msg, detachedSignedContent,
2425 sizeof(detachedSignedContent), TRUE);
2426 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2427 /* while a third fails. */
2428 ret = CryptMsgUpdate(msg, detachedSignedContent,
2429 sizeof(detachedSignedContent), TRUE);
2430 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2431 "expected CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
2432 CryptMsgClose(msg);
2434 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2435 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2436 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2437 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2438 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2439 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2440 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2441 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2442 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2444 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2445 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2446 "expected CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
2447 CryptMsgClose(msg);
2449 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2450 NULL);
2451 SetLastError(0xdeadbeef);
2452 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2453 sizeof(envelopedEmptyBareContent), TRUE);
2454 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2455 CryptMsgClose(msg);
2457 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2458 NULL);
2459 SetLastError(0xdeadbeef);
2460 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2461 sizeof(envelopedEmptyContent), TRUE);
2462 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2463 "expected CRYPT_E_ASN1_BADTAG, got %08lx\n", GetLastError());
2464 CryptMsgClose(msg);
2466 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2467 SetLastError(0xdeadbeef);
2468 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2469 sizeof(envelopedEmptyBareContent), TRUE);
2470 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2471 "expected CRYPT_E_ASN1_BADTAG, got %08lx\n", GetLastError());
2472 CryptMsgClose(msg);
2474 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2475 SetLastError(0xdeadbeef);
2476 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2477 sizeof(envelopedEmptyContent), TRUE);
2478 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2479 CryptMsgClose(msg);
2481 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2482 NULL);
2483 SetLastError(0xdeadbeef);
2484 ret = CryptMsgUpdate(msg, envelopedBareContentWithoutData,
2485 sizeof(envelopedBareContentWithoutData), TRUE);
2486 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2487 CryptMsgClose(msg);
2490 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2491 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2493 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2494 const CMSG_SIGNER_INFO *expected)
2496 ok(got->dwVersion == expected->dwVersion, "Expected version %ld, got %ld\n",
2497 expected->dwVersion, got->dwVersion);
2498 ok(got->Issuer.cbData == expected->Issuer.cbData,
2499 "Expected issuer size %ld, got %ld\n", expected->Issuer.cbData,
2500 got->Issuer.cbData);
2501 ok(!memcmp(got->Issuer.pbData, expected->Issuer.pbData, got->Issuer.cbData),
2502 "Unexpected issuer\n");
2503 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2504 "Expected serial number size %ld, got %ld\n", expected->SerialNumber.cbData,
2505 got->SerialNumber.cbData);
2506 ok(!memcmp(got->SerialNumber.pbData, expected->SerialNumber.pbData,
2507 got->SerialNumber.cbData), "Unexpected serial number\n");
2508 /* FIXME: check more things */
2511 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2512 const CMSG_CMS_SIGNER_INFO *expected)
2514 ok(got->dwVersion == expected->dwVersion, "Expected version %ld, got %ld\n",
2515 expected->dwVersion, got->dwVersion);
2516 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2517 "Expected id choice %ld, got %ld\n", expected->SignerId.dwIdChoice,
2518 got->SignerId.dwIdChoice);
2519 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2521 if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2523 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2524 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2525 "Expected issuer size %ld, got %ld\n",
2526 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2527 U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2528 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2529 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2530 U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2531 "Unexpected issuer\n");
2532 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2533 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2534 "Expected serial number size %ld, got %ld\n",
2535 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2536 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2537 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2538 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2539 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2540 "Unexpected serial number\n");
2542 else
2544 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2545 "expected key id size %ld, got %ld\n",
2546 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2547 ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2548 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2549 "unexpected key id\n");
2552 /* FIXME: check more things */
2555 static const BYTE signedWithCertAndCrlComputedHash[] = {
2556 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2557 0x2f };
2558 static BYTE keyIdIssuer[] = {
2559 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2560 0x0a,0x07,0x01,0x04,0x01,0x01 };
2561 static const BYTE publicPrivateKeyPair[] = {
2562 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00,
2563 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b,
2564 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50,
2565 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54,
2566 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39,
2567 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7,
2568 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48,
2569 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17,
2570 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54,
2571 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33,
2572 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52,
2573 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e,
2574 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61,
2575 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb,
2576 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02,
2577 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90,
2578 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e,
2579 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce,
2580 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14,
2581 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5,
2582 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5,
2583 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94,
2584 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68,
2585 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71,
2586 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25,
2587 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc,
2588 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a,
2589 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64,
2590 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77,
2591 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68,
2592 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab,
2593 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9,
2594 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed,
2595 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01,
2596 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e,
2597 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71,
2598 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0,
2599 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87,
2600 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b,
2601 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e };
2602 static const BYTE envelopedMessage[] = {
2603 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,
2604 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,
2605 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,
2606 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,
2607 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
2608 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65,
2609 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae,
2610 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1,
2611 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51,
2612 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf,
2613 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b,
2614 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e,
2615 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e,
2616 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70,
2617 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,
2618 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,
2619 0x04,0x5f,0x80,0xf2,0x17 };
2620 static const BYTE envelopedBareMessage[] = {
2621 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2622 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2623 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2624 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2625 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d,
2626 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d,
2627 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5,
2628 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e,
2629 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2,
2630 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4,
2631 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70,
2632 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c,
2633 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55,
2634 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2635 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c,
2636 0x2d,0xa3,0x6e };
2637 static const BYTE envelopedMessageWith3Recps[] = {
2638 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,
2639 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e,
2640 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,
2641 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,
2642 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,
2643 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e,
2644 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba,
2645 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f,
2646 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5,
2647 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21,
2648 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae,
2649 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0,
2650 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96,
2651 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae,
2652 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,
2653 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,
2654 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6,
2655 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
2656 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf,
2657 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9,
2658 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3,
2659 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02,
2660 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70,
2661 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3,
2662 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74,
2663 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94,
2664 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7,
2665 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,
2666 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,
2667 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
2668 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98,
2669 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5,
2670 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9,
2671 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3,
2672 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8,
2673 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac,
2674 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc,
2675 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5,
2676 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1,
2677 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
2678 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,
2679 0x80,0x04,0x4e,0x99,0x9d,0x4c };
2680 static const BYTE serialNumber[] = {
2681 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2,
2682 0x1c };
2683 static const BYTE issuer[] = {
2684 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 };
2686 static void test_decode_msg_get_param(void)
2688 HCRYPTMSG msg;
2689 HCRYPTPROV hCryptProv;
2690 HCRYPTKEY key = 0;
2691 BOOL ret;
2692 DWORD size = 0, value, req_size;
2693 LPBYTE buf;
2694 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2696 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2697 SetLastError(0xdeadbeef);
2698 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2699 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2700 "Expected CRYPT_E_INVALID_MSG_TYPE, got %lx\n", GetLastError());
2701 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2702 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2703 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2704 sizeof(msgData));
2705 CryptMsgClose(msg);
2707 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2708 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2710 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2711 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2712 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2713 emptyHashParam, sizeof(emptyHashParam));
2715 CryptMsgClose(msg);
2716 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2717 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2718 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2719 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2720 sizeof(msgData));
2721 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2722 sizeof(hashParam));
2723 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2724 hashParam, sizeof(hashParam));
2726 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2727 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2728 buf = CryptMemAlloc(size);
2729 if (buf)
2731 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2732 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2733 ok(size == sizeof(hashParam), "Unexpected size %ld\n", size);
2734 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2735 CryptMemFree(buf);
2737 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2738 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2739 value = CMSG_HASHED_DATA_V0;
2740 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2741 sizeof(value));
2742 CryptMsgClose(msg);
2744 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2745 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2746 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2747 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2748 sizeof(msgData));
2749 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2750 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2751 size = sizeof(value);
2752 value = 2112;
2753 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2754 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2755 ok(value == 1, "Expected 1 signer, got %ld\n", value);
2756 size = 0;
2757 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2758 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2759 buf = CryptMemAlloc(size);
2760 if (buf)
2762 CMSG_SIGNER_INFO signer = { 0 };
2764 signer.dwVersion = 1;
2765 signer.Issuer.cbData = sizeof(encodedCommonName);
2766 signer.Issuer.pbData = encodedCommonName;
2767 signer.SerialNumber.cbData = sizeof(serialNum);
2768 signer.SerialNumber.pbData = serialNum;
2769 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2770 req_size = size;
2771 size += 10;
2772 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2773 ok(size == req_size, "size = %lu, expected %lu\n", size, req_size);
2774 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2775 CryptMemFree(buf);
2777 /* Getting the CMS signer info of a PKCS7 message is possible. */
2778 size = 0;
2779 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2780 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2781 buf = CryptMemAlloc(size);
2782 if (buf)
2784 CMSG_CMS_SIGNER_INFO signer = { 0 };
2786 signer.dwVersion = 1;
2787 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2788 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2789 sizeof(encodedCommonName);
2790 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2791 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2792 sizeof(serialNum);
2793 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2794 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2795 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2796 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2797 CryptMemFree(buf);
2799 /* index is ignored when getting signer count */
2800 size = sizeof(value);
2801 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2802 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2803 ok(value == 1, "Expected 1 signer, got %ld\n", value);
2804 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2805 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2806 ok(value == 0, "Expected 0 certs, got %ld\n", value);
2807 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2808 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2809 ok(value == 0, "Expected 0 CRLs, got %ld\n", value);
2810 CryptMsgClose(msg);
2811 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2812 NULL);
2813 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2814 sizeof(signedWithCertAndCrlBareContent), TRUE);
2815 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2816 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2817 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2818 ok(value == 1, "Expected 1 cert, got %ld\n", value);
2819 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2820 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2821 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2822 ok(value == 1, "Expected 1 CRL, got %ld\n", value);
2823 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2824 check_param("signed with cert and CRL computed hash", msg,
2825 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2826 sizeof(signedWithCertAndCrlComputedHash));
2827 CryptMsgClose(msg);
2829 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2830 ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
2831 sizeof(signedKeyIdEmptyContent), TRUE);
2832 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
2833 size = sizeof(value);
2834 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2835 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2836 ok(value == 1, "Expected 1 signer, got %ld\n", value);
2837 /* Getting the regular (non-CMS) signer info from a CMS message is also
2838 * possible..
2840 size = 0;
2841 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2842 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2843 buf = CryptMemAlloc(size);
2844 if (buf)
2846 CMSG_SIGNER_INFO signer;
2847 BYTE zero = 0;
2849 /* and here's the little oddity: for a CMS message using the key id
2850 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
2851 * a signer with a zero (not empty) serial number, and whose issuer is
2852 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
2853 * and value of the key id.
2855 signer.dwVersion = CMSG_SIGNED_DATA_V3;
2856 signer.Issuer.cbData = sizeof(keyIdIssuer);
2857 signer.Issuer.pbData = keyIdIssuer;
2858 signer.SerialNumber.cbData = 1;
2859 signer.SerialNumber.pbData = &zero;
2860 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2861 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2862 CryptMemFree(buf);
2864 size = 0;
2865 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2866 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2867 buf = CryptMemAlloc(size);
2868 if (buf)
2870 CMSG_CMS_SIGNER_INFO signer = { 0 };
2872 signer.dwVersion = CMSG_SIGNED_DATA_V3;
2873 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2874 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
2875 U(signer.SignerId).KeyId.pbData = serialNum;
2876 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2877 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2878 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2879 CryptMemFree(buf);
2881 CryptMsgClose(msg);
2883 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2884 NULL);
2885 CryptMsgUpdate(msg, envelopedEmptyBareContent,
2886 sizeof(envelopedEmptyBareContent), TRUE);
2887 check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL,
2889 CryptMsgClose(msg);
2891 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2892 CryptMsgUpdate(msg, envelopedEmptyContent, sizeof(envelopedEmptyContent),
2893 TRUE);
2894 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2895 CryptMsgClose(msg);
2897 CryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL,
2898 CRYPT_VERIFYCONTEXT);
2899 SetLastError(0xdeadbeef);
2900 ret = CryptImportKey(hCryptProv, publicPrivateKeyPair,
2901 sizeof(publicPrivateKeyPair), 0, 0, &key);
2902 ok(ret, "CryptImportKey failed: %08lx\n", GetLastError());
2904 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2905 CryptMsgUpdate(msg, envelopedMessage, sizeof(envelopedMessage), TRUE);
2906 check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM,
2907 envelopedMessage + sizeof(envelopedMessage) - 4, 4);
2909 decryptPara.hCryptProv = hCryptProv;
2910 SetLastError(0xdeadbeef);
2911 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2912 ok(ret, "CryptMsgControl failed: %08lx\n", GetLastError());
2913 decryptPara.hCryptProv = 0;
2914 SetLastError(0xdeadbeef);
2915 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2916 ok(!ret && GetLastError() == CRYPT_E_ALREADY_DECRYPTED,
2917 "expected CRYPT_E_ALREADY_DECRYPTED, got %08lx\n", GetLastError());
2918 check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData, sizeof(msgData));
2919 CryptMsgClose(msg);
2921 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2922 NULL);
2923 CryptMsgUpdate(msg, envelopedBareMessage, sizeof(envelopedBareMessage),
2924 TRUE);
2925 check_param("enveloped bare message before decrypting", msg,
2926 CMSG_CONTENT_PARAM, envelopedBareMessage +
2927 sizeof(envelopedBareMessage) - 4, 4);
2929 decryptPara.hCryptProv = hCryptProv;
2930 SetLastError(0xdeadbeef);
2931 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2932 ok(ret, "CryptMsgControl failed: %08lx\n", GetLastError());
2933 check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData, sizeof(msgData));
2934 CryptMsgClose(msg);
2936 if (key)
2937 CryptDestroyKey(key);
2938 CryptReleaseContext(hCryptProv, 0);
2940 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2941 CryptMsgUpdate(msg, envelopedMessageWith3Recps,
2942 sizeof(envelopedMessageWith3Recps), TRUE);
2943 value = 3;
2944 check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM,
2945 (const BYTE *)&value, sizeof(value));
2946 size = 0;
2947 SetLastError(0xdeadbeef);
2948 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 3, NULL, &size);
2949 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
2950 "expected CRYPT_E_INVALID_INDEX, got %08lx\n", GetLastError());
2951 size = 0;
2952 SetLastError(0xdeadbeef);
2953 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, NULL, &size);
2954 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2955 ok(size >= 142, "unexpected size: %lu\n", size);
2956 if (ret)
2957 buf = CryptMemAlloc(size);
2958 else
2959 buf = NULL;
2960 if (buf)
2962 CERT_INFO *certInfo = (CERT_INFO *)buf;
2964 SetLastError(0xdeadbeef);
2965 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, buf, &size);
2966 ok(ret, "CryptMsgGetParam failed: %08lx\n", GetLastError());
2967 ok(certInfo->SerialNumber.cbData == sizeof(serialNumber),
2968 "unexpected serial number size: %lu\n", certInfo->SerialNumber.cbData);
2969 ok(!memcmp(certInfo->SerialNumber.pbData, serialNumber,
2970 sizeof(serialNumber)), "unexpected serial number\n");
2971 ok(certInfo->Issuer.cbData == sizeof(issuer),
2972 "unexpected issuer size: %lu\n", certInfo->Issuer.cbData);
2973 ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)),
2974 "unexpected issuer\n");
2975 CryptMemFree(buf);
2977 CryptMsgClose(msg);
2980 static void test_decode_msg(void)
2982 test_decode_msg_update();
2983 test_decode_msg_get_param();
2986 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2987 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2988 static BYTE encodedPubKey[] = {
2989 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2990 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2991 0x0d,0x0e,0x0f };
2992 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2993 static BYTE mod_encoded[] = {
2994 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2995 0x01,0x00,0x01 };
2997 static void test_msg_control(void)
2999 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3000 BOOL ret;
3001 HCRYPTMSG msg;
3002 DWORD i;
3003 CERT_INFO certInfo = { 0 };
3004 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
3005 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
3006 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
3008 /* Crashes
3009 ret = CryptMsgControl(NULL, 0, 0, NULL);
3012 /* Data encode messages don't allow any sort of control.. */
3013 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
3014 NULL);
3015 /* either with no prior update.. */
3016 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
3018 SetLastError(0xdeadbeef);
3019 ret = CryptMsgControl(msg, 0, i, NULL);
3020 ok(!ret && GetLastError() == E_INVALIDARG,
3021 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3023 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3024 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3025 /* or after an update. */
3026 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
3028 SetLastError(0xdeadbeef);
3029 ret = CryptMsgControl(msg, 0, i, NULL);
3030 ok(!ret && GetLastError() == E_INVALIDARG,
3031 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3033 CryptMsgClose(msg);
3035 /* Hash encode messages don't allow any sort of control.. */
3036 hashInfo.cbSize = sizeof(hashInfo);
3037 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
3038 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
3039 NULL, NULL);
3040 /* either with no prior update.. */
3041 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
3043 SetLastError(0xdeadbeef);
3044 ret = CryptMsgControl(msg, 0, i, NULL);
3045 ok(!ret && GetLastError() == E_INVALIDARG,
3046 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3048 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3049 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3050 /* or after an update. */
3051 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
3053 SetLastError(0xdeadbeef);
3054 ret = CryptMsgControl(msg, 0, i, NULL);
3055 ok(!ret && GetLastError() == E_INVALIDARG,
3056 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3058 CryptMsgClose(msg);
3060 /* Signed encode messages likewise don't allow any sort of control.. */
3061 signInfo.cbSize = sizeof(signInfo);
3062 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
3063 NULL, NULL);
3064 /* either before an update.. */
3065 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
3067 SetLastError(0xdeadbeef);
3068 ret = CryptMsgControl(msg, 0, i, NULL);
3069 ok(!ret && GetLastError() == E_INVALIDARG,
3070 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3072 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3073 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3074 /* or after an update. */
3075 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
3077 SetLastError(0xdeadbeef);
3078 ret = CryptMsgControl(msg, 0, i, NULL);
3079 ok(!ret && GetLastError() == E_INVALIDARG,
3080 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3082 CryptMsgClose(msg);
3084 /* Decode messages behave a bit differently. */
3085 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3086 /* Bad control type */
3087 SetLastError(0xdeadbeef);
3088 ret = CryptMsgControl(msg, 0, 0, NULL);
3089 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3090 "Expected CRYPT_E_CONTROL_TYPE, got %08lx\n", GetLastError());
3091 SetLastError(0xdeadbeef);
3092 ret = CryptMsgControl(msg, 1, 0, NULL);
3093 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3094 "Expected CRYPT_E_CONTROL_TYPE, got %08lx\n", GetLastError());
3095 /* Can't verify the hash of an indeterminate-type message */
3096 SetLastError(0xdeadbeef);
3097 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3098 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3099 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3100 /* Crashes
3101 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
3103 /* Can't decrypt an indeterminate-type message */
3104 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3105 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3106 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3107 CryptMsgClose(msg);
3109 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL, NULL);
3110 /* Can't verify the hash of an empty message */
3111 SetLastError(0xdeadbeef);
3112 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3113 todo_wine
3114 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3115 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
3116 /* Crashes
3117 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3119 /* Can't verify the signature of a hash message */
3120 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3121 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3122 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3123 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent), TRUE);
3124 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3125 ok(!ret, "Expected failure\n");
3126 CryptMsgClose(msg);
3128 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3129 NULL);
3130 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
3131 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3132 ok(ret, "CryptMsgControl failed: %08lx\n", GetLastError());
3133 /* Can't decrypt an indeterminate-type message */
3134 SetLastError(0xdeadbeef);
3135 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3136 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3137 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3138 CryptMsgClose(msg);
3140 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3141 NULL, NULL);
3142 /* Can't verify the hash of a detached message before it's been updated. */
3143 SetLastError(0xdeadbeef);
3144 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3145 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3146 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3147 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3148 TRUE);
3149 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3150 /* Still can't verify the hash of a detached message with the content
3151 * of the detached hash given..
3153 SetLastError(0xdeadbeef);
3154 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3155 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
3156 "Expected CRYPT_E_HASH_VALUE, got %08lx\n", GetLastError());
3157 /* and giving the content of the message after attempting to verify the
3158 * hash fails.
3160 SetLastError(0xdeadbeef);
3161 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3162 todo_wine
3163 ok(!ret && (GetLastError() == NTE_BAD_HASH_STATE || GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
3164 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3165 "got %08lx\n", GetLastError());
3166 CryptMsgClose(msg);
3168 /* Finally, verifying the hash of a detached message in the correct order:
3169 * 1. Update with the detached hash message
3170 * 2. Update with the content of the message
3171 * 3. Verifying the hash of the message
3172 * succeeds.
3174 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3175 NULL, NULL);
3176 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3177 TRUE);
3178 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3179 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3180 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3181 SetLastError(0xdeadbeef);
3182 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3183 ok(ret, "CryptMsgControl failed: %08lx\n", GetLastError());
3184 CryptMsgClose(msg);
3186 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3187 NULL);
3188 /* Can't verify the hash of a signed message */
3189 SetLastError(0xdeadbeef);
3190 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3191 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3192 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3193 /* Can't decrypt a signed message */
3194 SetLastError(0xdeadbeef);
3195 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3196 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3197 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3198 /* Crash
3199 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3200 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3202 CryptMsgUpdate(msg, signedWithCertBareContent,
3203 sizeof(signedWithCertBareContent), TRUE);
3204 /* With an empty cert info, the signer can't be found in the message (and
3205 * the signature can't be verified.
3207 SetLastError(0xdeadbeef);
3208 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3209 ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
3210 "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08lx\n", GetLastError());
3211 /* The cert info is expected to have an issuer, serial number, and public
3212 * key info set.
3214 certInfo.SerialNumber.cbData = sizeof(serialNum);
3215 certInfo.SerialNumber.pbData = serialNum;
3216 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3217 certInfo.Issuer.pbData = encodedCommonName;
3218 SetLastError(0xdeadbeef);
3219 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3220 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
3221 "Expected CRYPT_E_ASN1_EOD, got %08lx\n", GetLastError());
3222 CryptMsgClose(msg);
3223 /* This cert has a public key, but it's not in a usable form */
3224 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3225 NULL);
3226 ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
3227 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
3228 if (ret)
3230 /* Again, cert info needs to have a public key set */
3231 SetLastError(0xdeadbeef);
3232 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3233 ok(!ret &&
3234 (GetLastError() == CRYPT_E_ASN1_EOD ||
3235 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3236 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08lx\n", GetLastError());
3237 /* The public key is supposed to be in encoded form.. */
3238 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3239 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3240 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
3241 SetLastError(0xdeadbeef);
3242 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3243 ok(!ret &&
3244 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3245 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3246 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08lx\n", GetLastError());
3247 /* but not as a X509_PUBLIC_KEY_INFO.. */
3248 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3249 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
3250 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
3251 SetLastError(0xdeadbeef);
3252 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3253 ok(!ret &&
3254 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3255 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3256 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08lx\n", GetLastError());
3257 /* This decodes successfully, but it doesn't match any key in the message */
3258 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
3259 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
3260 SetLastError(0xdeadbeef);
3261 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3262 /* In Wine's rsaenh, this fails to decode because the key length is too
3263 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
3264 * now.
3266 todo_wine
3267 ok(!ret &&
3268 (GetLastError() == NTE_BAD_SIGNATURE ||
3269 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3270 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08lx\n", GetLastError());
3272 CryptMsgClose(msg);
3273 /* A message with no data doesn't have a valid signature */
3274 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3275 ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
3276 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
3277 if (ret)
3279 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3280 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
3281 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
3282 SetLastError(0xdeadbeef);
3283 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3284 ok(!ret &&
3285 (GetLastError() == NTE_BAD_SIGNATURE ||
3286 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3287 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08lx\n", GetLastError());
3289 CryptMsgClose(msg);
3290 /* Finally, this succeeds */
3291 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3292 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3293 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3294 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3295 ok(ret, "CryptMsgControl failed: %08lx\n", GetLastError());
3296 CryptMsgClose(msg);
3298 /* Test verifying signature of a detached signed message */
3299 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3300 NULL, NULL);
3301 ret = CryptMsgUpdate(msg, detachedSignedContent,
3302 sizeof(detachedSignedContent), TRUE);
3303 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3304 /* Can't verify the sig without having updated the data */
3305 SetLastError(0xdeadbeef);
3306 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3307 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
3308 "expected NTE_BAD_SIGNATURE, got %08lx\n",
3309 GetLastError());
3310 /* Now that the signature's been checked, can't do the final update */
3311 SetLastError(0xdeadbeef);
3312 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3313 todo_wine
3314 ok(!ret && (GetLastError() == NTE_BAD_HASH_STATE || GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
3315 "expected NTE_BAD_HASH_STATE or CRYPT_E_MSG_ERROR, got %08lx\n", GetLastError());
3316 CryptMsgClose(msg);
3317 /* Updating with the detached portion of the message and the data of the
3318 * the message allows the sig to be verified.
3320 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3321 NULL, NULL);
3322 ret = CryptMsgUpdate(msg, detachedSignedContent,
3323 sizeof(detachedSignedContent), TRUE);
3324 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3325 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3326 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3327 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3328 ok(ret, "CryptMsgControl failed: %08lx\n", GetLastError());
3329 CryptMsgClose(msg);
3331 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3332 NULL);
3333 decryptPara.cbSize = 0;
3334 SetLastError(0xdeadbeef);
3335 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3336 ok(!ret && GetLastError() == E_INVALIDARG,
3337 "expected E_INVALIDARG, got %08lx\n", GetLastError());
3338 decryptPara.cbSize = sizeof(decryptPara);
3340 SetLastError(0xdeadbeef);
3341 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3342 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3343 "expected CRYPT_E_INVALID_MSG_TYPE, got %08lx\n", GetLastError());
3345 SetLastError(0xdeadbeef);
3346 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
3347 sizeof(envelopedEmptyBareContent), TRUE);
3348 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3349 SetLastError(0xdeadbeef);
3350 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3351 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3352 "expected CRYPT_E_INVALID_INDEX, got %08lx\n", GetLastError());
3353 CryptMsgClose(msg);
3355 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3356 NULL);
3357 SetLastError(0xdeadbeef);
3358 ret = CryptMsgUpdate(msg, envelopedBareMessage,
3359 sizeof(envelopedBareMessage), TRUE);
3360 ok(ret, "CryptMsgUpdate failed: %08lx\n", GetLastError());
3361 SetLastError(0xdeadbeef);
3362 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3363 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
3364 "expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
3365 CryptMsgClose(msg);
3368 static void test_msg_get_and_verify_signer(void)
3370 BOOL ret;
3371 HCRYPTMSG msg;
3372 PCCERT_CONTEXT signer;
3373 DWORD signerIndex;
3374 HCERTSTORE store;
3376 /* Crash */
3377 if (0)
3379 CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
3380 CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3383 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3384 /* An empty message has no signer */
3385 SetLastError(0xdeadbeef);
3386 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3387 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3388 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3389 /* The signer is cleared on error */
3390 signer = (PCCERT_CONTEXT)0xdeadbeef;
3391 SetLastError(0xdeadbeef);
3392 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3393 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3394 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3395 ok(!signer, "expected signer to be NULL\n");
3396 /* The signer index is also cleared on error */
3397 signerIndex = 0xdeadbeef;
3398 SetLastError(0xdeadbeef);
3399 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3400 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3401 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3402 ok(!signerIndex, "expected 0, got %ld\n", signerIndex);
3403 /* An unsigned message (msgData isn't a signed message at all)
3404 * likewise has no signer.
3406 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3407 SetLastError(0xdeadbeef);
3408 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3409 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3410 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3411 CryptMsgClose(msg);
3413 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3414 /* A "signed" message created with no signer cert likewise has no signer */
3415 ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
3416 if (ret)
3418 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3419 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3420 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3422 CryptMsgClose(msg);
3424 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3425 /* A signed message succeeds, .. */
3426 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3427 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3428 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3429 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08lx\n", GetLastError());
3430 /* the signer index can be retrieved, .. */
3431 signerIndex = 0xdeadbeef;
3432 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3433 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08lx\n", GetLastError());
3434 if (ret)
3435 ok(signerIndex == 0, "expected 0, got %ld\n", signerIndex);
3436 /* as can the signer cert. */
3437 signer = (PCCERT_CONTEXT)0xdeadbeef;
3438 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3439 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08lx\n", GetLastError());
3440 if (ret)
3441 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3442 "expected a valid signer\n");
3443 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3444 CertFreeCertificateContext(signer);
3445 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3447 signerIndex = 0xdeadbeef;
3448 SetLastError(0xdeadbeef);
3449 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3450 NULL, &signerIndex);
3451 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3452 "expected CRYPT_E_INVALID_INDEX, got 0x%08lx\n", GetLastError());
3453 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3454 * message signer not to be found.
3456 SetLastError(0xdeadbeef);
3457 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3458 NULL, NULL);
3459 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3460 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3461 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3462 * the message signer not to be found.
3464 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3465 CERT_STORE_CREATE_NEW_FLAG, NULL);
3466 SetLastError(0xdeadbeef);
3467 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3468 NULL, NULL);
3469 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3470 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08lx\n", GetLastError());
3471 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3472 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3473 CERT_STORE_ADD_ALWAYS, NULL);
3474 ok(ret, "CertAddEncodedCertificateToStore failed: 0x%08lx\n", GetLastError());
3475 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3476 * the signer succeeds.
3478 SetLastError(0xdeadbeef);
3479 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3480 NULL, NULL);
3481 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08lx\n", GetLastError());
3482 CertCloseStore(store, 0);
3483 CryptMsgClose(msg);
3486 START_TEST(msg)
3488 /* Basic parameter checking tests */
3489 test_msg_open_to_encode();
3490 test_msg_open_to_decode();
3491 test_msg_get_param();
3492 test_msg_close();
3493 test_msg_control();
3495 /* Message-type specific tests */
3496 test_data_msg();
3497 test_hash_msg();
3498 test_signed_msg();
3499 test_enveloped_msg();
3500 test_decode_msg();
3502 test_msg_get_and_verify_signer();