push 2f3ca95c4974ba229fa47d638b3044f50788f3bd
[wine/hacks.git] / dlls / crypt32 / tests / msg.c
blob495f2f07216b31de077f8a51eccdf451a3ccf8db
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 BOOL have_nt;
33 static char oid_rsa_md5[] = szOID_RSA_MD5;
35 static BOOL (WINAPI * pCryptAcquireContextA)
36 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
37 static BOOL (WINAPI * pCryptAcquireContextW)
38 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
40 static void init_function_pointers(void)
42 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
44 #define GET_PROC(dll, func) \
45 p ## func = (void *)GetProcAddress(dll, #func); \
46 if(!p ## func) \
47 trace("GetProcAddress(%s) failed\n", #func);
49 GET_PROC(hAdvapi32, CryptAcquireContextA)
50 GET_PROC(hAdvapi32, CryptAcquireContextW)
52 #undef GET_PROC
55 static void test_msg_open_to_encode(void)
57 HCRYPTMSG msg;
59 /* Crash
60 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
61 NULL, NULL);
62 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
63 NULL);
64 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
65 NULL);
68 /* Bad encodings */
69 SetLastError(0xdeadbeef);
70 msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
71 ok(!msg && GetLastError() == E_INVALIDARG,
72 "Expected E_INVALIDARG, got %x\n", GetLastError());
73 SetLastError(0xdeadbeef);
74 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
75 ok(!msg && GetLastError() == E_INVALIDARG,
76 "Expected E_INVALIDARG, got %x\n", GetLastError());
78 /* Bad message types */
79 SetLastError(0xdeadbeef);
80 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
81 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
82 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
83 SetLastError(0xdeadbeef);
84 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
85 NULL, NULL, NULL);
86 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
87 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
88 SetLastError(0xdeadbeef);
89 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
90 CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
91 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
92 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
93 SetLastError(0xdeadbeef);
94 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
95 NULL, NULL);
96 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
97 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
100 static void test_msg_open_to_decode(void)
102 HCRYPTMSG msg;
103 CMSG_STREAM_INFO streamInfo = { 0 };
105 SetLastError(0xdeadbeef);
106 msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
107 ok(!msg && GetLastError() == E_INVALIDARG,
108 "Expected E_INVALIDARG, got %x\n", GetLastError());
110 /* Bad encodings */
111 SetLastError(0xdeadbeef);
112 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
113 ok(!msg && GetLastError() == E_INVALIDARG,
114 "Expected E_INVALIDARG, got %x\n", GetLastError());
115 SetLastError(0xdeadbeef);
116 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
117 ok(!msg && GetLastError() == E_INVALIDARG,
118 "Expected E_INVALIDARG, got %x\n", GetLastError());
120 /* The message type can be explicit... */
121 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
122 NULL);
123 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
124 CryptMsgClose(msg);
125 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
126 NULL);
127 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
128 CryptMsgClose(msg);
129 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
130 NULL);
131 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
132 CryptMsgClose(msg);
133 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
134 NULL);
135 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
136 CryptMsgClose(msg);
137 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
138 CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
139 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
140 CryptMsgClose(msg);
141 /* or implicit.. */
142 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
143 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
144 CryptMsgClose(msg);
145 /* or even invalid. */
146 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
147 NULL);
148 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
149 CryptMsgClose(msg);
150 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
151 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
152 CryptMsgClose(msg);
154 /* And even though the stream info parameter "must be set to NULL" for
155 * CMSG_HASHED, it's still accepted.
157 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
158 &streamInfo);
159 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
160 CryptMsgClose(msg);
163 static void test_msg_get_param(void)
165 BOOL ret;
166 HCRYPTMSG msg;
167 DWORD size, i, value;
168 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
169 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
171 /* Crash
172 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
173 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
174 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
177 /* Decoded messages */
178 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
179 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
180 /* For decoded messages, the type is always available */
181 size = 0;
182 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
183 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
184 size = sizeof(value);
185 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
186 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
187 /* For this (empty) message, the type isn't set */
188 ok(value == 0, "Expected type 0, got %d\n", value);
189 CryptMsgClose(msg);
191 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
192 NULL);
193 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
194 /* For explicitly typed messages, the type is known. */
195 size = sizeof(value);
196 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
197 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
198 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
199 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
201 size = 0;
202 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
203 ok(!ret, "Parameter %d: expected failure\n", i);
205 CryptMsgClose(msg);
207 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
208 NULL);
209 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
210 size = sizeof(value);
211 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
212 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
213 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
214 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
216 size = 0;
217 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
218 ok(!ret, "Parameter %d: expected failure\n", i);
220 CryptMsgClose(msg);
222 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
223 NULL);
224 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
225 size = sizeof(value);
226 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
227 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
228 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
229 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
231 size = 0;
232 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
233 ok(!ret, "Parameter %d: expected failure\n", i);
235 CryptMsgClose(msg);
237 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
238 NULL);
239 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
240 size = sizeof(value);
241 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
242 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
243 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
244 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
246 size = 0;
247 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
248 ok(!ret, "Parameter %d: expected failure\n", i);
250 CryptMsgClose(msg);
252 /* Explicitly typed messages get their types set, even if they're invalid */
253 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
254 NULL);
255 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
256 size = sizeof(value);
257 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
258 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
259 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
260 CryptMsgClose(msg);
262 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
263 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
264 size = sizeof(value);
265 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
266 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
267 ok(value == 1000, "Expected 1000, got %d\n", value);
268 CryptMsgClose(msg);
271 static void test_msg_close(void)
273 BOOL ret;
274 HCRYPTMSG msg;
276 /* NULL succeeds.. */
277 ret = CryptMsgClose(NULL);
278 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
279 /* but an arbitrary pointer crashes. */
280 if (0)
281 ret = CryptMsgClose((HCRYPTMSG)1);
282 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
283 NULL);
284 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
285 ret = CryptMsgClose(msg);
286 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
289 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
290 const BYTE *expected, DWORD expectedSize)
292 DWORD size;
293 LPBYTE buf;
294 BOOL ret;
296 size = 0xdeadbeef;
297 ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
298 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
299 buf = HeapAlloc(GetProcessHeap(), 0, size);
300 ret = CryptMsgGetParam(msg, param, 0, buf, &size);
301 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
302 ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
303 expectedSize, size);
304 if (size == expectedSize && size)
305 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
306 HeapFree(GetProcessHeap(), 0, buf);
309 static void test_data_msg_open(void)
311 HCRYPTMSG msg;
312 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
313 CMSG_STREAM_INFO streamInfo = { 0 };
314 char oid[] = "1.2.3";
316 /* The data message type takes no additional info */
317 SetLastError(0xdeadbeef);
318 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
319 NULL, NULL);
320 ok(!msg && GetLastError() == E_INVALIDARG,
321 "Expected E_INVALIDARG, got %x\n", GetLastError());
322 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
323 NULL);
324 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
325 CryptMsgClose(msg);
327 /* An empty stream info is allowed. */
328 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
329 &streamInfo);
330 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
331 CryptMsgClose(msg);
333 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
334 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
335 NULL);
336 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
337 CryptMsgClose(msg);
338 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
339 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
340 CMSG_DATA, NULL, oid, NULL);
341 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
342 CryptMsgClose(msg);
343 /* and when a stream info is given, even though you're not supposed to be
344 * able to use anything but szOID_RSA_data when streaming is being used.
346 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
347 CMSG_DATA, NULL, oid, &streamInfo);
348 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
349 CryptMsgClose(msg);
352 static const BYTE msgData[] = { 1, 2, 3, 4 };
354 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
355 BOOL final)
357 return TRUE;
360 static void test_data_msg_update(void)
362 HCRYPTMSG msg;
363 BOOL ret;
364 CMSG_STREAM_INFO streamInfo = { 0 };
366 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
367 NULL);
368 /* Can't update a message that wasn't opened detached with final = FALSE */
369 SetLastError(0xdeadbeef);
370 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
371 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
372 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
373 /* Updating it with final = TRUE succeeds */
374 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
375 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
376 /* Any subsequent update will fail, as the last was final */
377 SetLastError(0xdeadbeef);
378 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
379 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
380 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
381 CryptMsgClose(msg);
383 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
384 NULL);
385 /* Can't update a message with no data */
386 SetLastError(0xdeadbeef);
387 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
388 /* This test returns FALSE on XP and earlier but TRUE on Vista, so can't be tested.
389 * GetLastError is either E_INVALIDARG (NT) or unset (9x/Vista), so it doesn't
390 * make sense to test this.
393 /* Curiously, a valid update will now fail as well, presumably because of
394 * the last (invalid, but final) update.
396 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
397 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
398 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
399 CryptMsgClose(msg);
401 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
402 CMSG_DATA, NULL, NULL, NULL);
403 /* Doesn't appear to be able to update CMSG-DATA with non-final updates */
404 SetLastError(0xdeadbeef);
405 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
406 ok(!ret && GetLastError() == E_INVALIDARG,
407 "Expected E_INVALIDARG, got %x\n", GetLastError());
408 SetLastError(0xdeadbeef);
409 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
410 ok(!ret && GetLastError() == E_INVALIDARG,
411 "Expected E_INVALIDARG, got %x\n", GetLastError());
412 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
413 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
414 CryptMsgClose(msg);
416 /* Calling update after opening with an empty stream info (with a bogus
417 * output function) yields an error:
419 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
420 &streamInfo);
421 SetLastError(0xdeadbeef);
422 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
423 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
424 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
425 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
426 GetLastError());
427 CryptMsgClose(msg);
428 /* Calling update with a valid output function succeeds, even if the data
429 * exceeds the size specified in the stream info.
431 streamInfo.pfnStreamOutput = nop_stream_output;
432 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
433 &streamInfo);
434 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
435 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
436 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
437 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
438 CryptMsgClose(msg);
441 static void test_data_msg_get_param(void)
443 HCRYPTMSG msg;
444 DWORD size;
445 BOOL ret;
446 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
448 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
449 NULL);
451 /* Content and bare content are always gettable when not streaming */
452 size = 0;
453 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
454 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
455 size = 0;
456 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
457 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
458 /* But for this type of message, the signer and hash aren't applicable,
459 * and the type isn't available.
461 size = 0;
462 SetLastError(0xdeadbeef);
463 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
464 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
465 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
466 SetLastError(0xdeadbeef);
467 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
468 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
469 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
470 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
471 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
472 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
473 CryptMsgClose(msg);
475 /* Can't get content or bare content when streaming */
476 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
477 NULL, &streamInfo);
478 SetLastError(0xdeadbeef);
479 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
480 ok(!ret && GetLastError() == E_INVALIDARG,
481 "Expected E_INVALIDARG, got %x\n", GetLastError());
482 SetLastError(0xdeadbeef);
483 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
484 ok(!ret && GetLastError() == E_INVALIDARG,
485 "Expected E_INVALIDARG, got %x\n", GetLastError());
486 CryptMsgClose(msg);
489 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
490 static const BYTE dataEmptyContent[] = {
491 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
492 0x04,0x00 };
493 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
494 static const BYTE dataContent[] = {
495 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
496 0x04,0x04,0x01,0x02,0x03,0x04 };
498 struct update_accum
500 DWORD cUpdates;
501 CRYPT_DATA_BLOB *updates;
504 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
505 DWORD cb, BOOL final)
507 struct update_accum *accum = (struct update_accum *)pvArg;
508 BOOL ret = FALSE;
510 if (accum->cUpdates)
511 accum->updates = CryptMemRealloc(accum->updates,
512 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
513 else
514 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
515 if (accum->updates)
517 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
519 blob->pbData = CryptMemAlloc(cb);
520 if (blob->pbData)
522 memcpy(blob->pbData, pb, cb);
523 blob->cbData = cb;
524 ret = TRUE;
526 accum->cUpdates++;
528 return ret;
531 /* The updates of a (bogus) definite-length encoded message */
532 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
533 0x07,0x01,0xa0,0x02,0x04,0x00 };
534 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
535 static CRYPT_DATA_BLOB b1[] = {
536 { sizeof(u1), u1 },
537 { sizeof(u2), u2 },
538 { sizeof(u2), u2 },
540 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
541 /* The updates of a definite-length encoded message */
542 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
543 0x07,0x01,0xa0,0x06,0x04,0x04 };
544 static CRYPT_DATA_BLOB b2[] = {
545 { sizeof(u3), u3 },
546 { sizeof(u2), u2 },
548 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
549 /* The updates of an indefinite-length encoded message */
550 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
551 0x07,0x01,0xa0,0x80,0x24,0x80 };
552 static BYTE u5[] = { 0x04,0x04 };
553 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
554 static CRYPT_DATA_BLOB b3[] = {
555 { sizeof(u4), u4 },
556 { sizeof(u5), u5 },
557 { sizeof(u2), u2 },
558 { sizeof(u5), u5 },
559 { sizeof(u2), u2 },
560 { sizeof(u6), u6 },
562 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
564 static void check_updates(LPCSTR header, const struct update_accum *expected,
565 const struct update_accum *got)
567 DWORD i;
569 ok(expected->cUpdates == got->cUpdates,
570 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
571 got->cUpdates);
572 if (expected->cUpdates == got->cUpdates)
573 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
575 ok(expected->updates[i].cbData == got->updates[i].cbData,
576 "%s, update %d: expected %d bytes, got %d\n", header, i,
577 expected->updates[i].cbData, got->updates[i].cbData);
578 if (expected->updates[i].cbData && expected->updates[i].cbData ==
579 got->updates[i].cbData)
580 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
581 got->updates[i].cbData), "%s, update %d: unexpected value\n",
582 header, i);
586 /* Frees the updates stored in accum */
587 static void free_updates(struct update_accum *accum)
589 DWORD i;
591 for (i = 0; i < accum->cUpdates; i++)
592 CryptMemFree(accum->updates[i].pbData);
593 CryptMemFree(accum->updates);
594 accum->updates = NULL;
595 accum->cUpdates = 0;
598 static void test_data_msg_encoding(void)
600 HCRYPTMSG msg;
601 BOOL ret;
602 static char oid[] = "1.2.3";
603 struct update_accum accum = { 0, NULL };
604 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
606 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
607 NULL);
608 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
609 dataEmptyBareContent, sizeof(dataEmptyBareContent));
610 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
611 sizeof(dataEmptyContent));
612 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
613 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
614 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
615 dataBareContent, sizeof(dataBareContent));
616 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
617 sizeof(dataContent));
618 CryptMsgClose(msg);
619 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
620 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
621 CMSG_DATA, NULL, NULL, NULL);
622 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
623 dataEmptyBareContent, sizeof(dataEmptyBareContent));
624 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
625 sizeof(dataEmptyContent));
626 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
627 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
628 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
629 dataBareContent, sizeof(dataBareContent));
630 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
631 sizeof(dataContent));
632 CryptMsgClose(msg);
633 /* The inner OID is apparently ignored */
634 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
635 NULL);
636 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
637 dataEmptyBareContent, sizeof(dataEmptyBareContent));
638 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
639 dataEmptyContent, sizeof(dataEmptyContent));
640 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
641 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
642 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
643 dataBareContent, sizeof(dataBareContent));
644 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
645 sizeof(dataContent));
646 CryptMsgClose(msg);
647 /* A streaming message is DER encoded if the length is not 0xffffffff, but
648 * curiously, updates aren't validated to make sure they don't exceed the
649 * stated length. (The resulting output will of course fail to decode.)
651 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
652 NULL, &streamInfo);
653 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
654 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
655 CryptMsgClose(msg);
656 check_updates("bogus data message with definite length", &a1, &accum);
657 free_updates(&accum);
658 /* A valid definite-length encoding: */
659 streamInfo.cbContent = sizeof(msgData);
660 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
661 NULL, &streamInfo);
662 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
663 CryptMsgClose(msg);
664 check_updates("data message with definite length", &a2, &accum);
665 free_updates(&accum);
666 /* An indefinite-length encoding: */
667 streamInfo.cbContent = 0xffffffff;
668 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
669 NULL, &streamInfo);
670 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
671 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
672 CryptMsgClose(msg);
673 check_updates("data message with indefinite length", &a3, &accum);
674 free_updates(&accum);
677 static void test_data_msg(void)
679 test_data_msg_open();
680 test_data_msg_update();
681 test_data_msg_get_param();
682 test_data_msg_encoding();
685 static void test_hash_msg_open(void)
687 HCRYPTMSG msg;
688 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
689 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
691 SetLastError(0xdeadbeef);
692 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
693 NULL, NULL);
694 ok(!msg && GetLastError() == E_INVALIDARG,
695 "Expected E_INVALIDARG, got %x\n", GetLastError());
696 hashInfo.cbSize = sizeof(hashInfo);
697 SetLastError(0xdeadbeef);
698 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
699 NULL, NULL);
700 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
701 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
702 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
703 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
704 NULL, NULL);
705 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
706 CryptMsgClose(msg);
707 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
708 CMSG_HASHED, &hashInfo, NULL, NULL);
709 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
710 CryptMsgClose(msg);
711 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
712 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
713 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
714 CryptMsgClose(msg);
717 static void test_hash_msg_update(void)
719 HCRYPTMSG msg;
720 BOOL ret;
721 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
722 { oid_rsa_md5, { 0, NULL } }, NULL };
723 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
725 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
726 CMSG_HASHED, &hashInfo, NULL, NULL);
727 /* Detached hashed messages opened in non-streaming mode allow non-final
728 * updates..
730 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
731 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
732 /* including non-final updates with no data.. */
733 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
734 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
735 /* and final updates with no data. */
736 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
737 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
738 /* But no updates are allowed after the final update. */
739 SetLastError(0xdeadbeef);
740 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
741 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
742 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
743 SetLastError(0xdeadbeef);
744 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
745 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
746 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
747 CryptMsgClose(msg);
748 /* Non-detached messages, in contrast, don't allow non-final updates in
749 * non-streaming mode.
751 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
752 NULL, NULL);
753 SetLastError(0xdeadbeef);
754 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
755 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
756 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
757 /* Final updates (including empty ones) are allowed. */
758 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
759 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
760 CryptMsgClose(msg);
761 /* And, of course, streaming mode allows non-final updates */
762 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
763 NULL, &streamInfo);
764 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
765 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
766 CryptMsgClose(msg);
767 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
768 * to be a bug, it isn't actually used - see encoding tests.)
770 streamInfo.pfnStreamOutput = NULL;
771 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
772 NULL, &streamInfo);
773 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
774 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
775 CryptMsgClose(msg);
778 static const BYTE emptyHashParam[] = {
779 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
780 0x7e };
782 static void test_hash_msg_get_param(void)
784 HCRYPTMSG msg;
785 BOOL ret;
786 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
787 { oid_rsa_md5, { 0, NULL } }, NULL };
788 DWORD size, value;
789 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
790 BYTE buf[16];
792 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
793 NULL, NULL);
794 /* Content and bare content are always gettable for non-streamed messages */
795 size = 0;
796 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
797 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
798 size = 0;
799 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
800 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
801 /* For an encoded hash message, the hash data aren't available */
802 SetLastError(0xdeadbeef);
803 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
804 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
805 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
806 /* The hash is also available. */
807 size = 0;
808 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
809 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
810 ok(size == sizeof(buf), "Unexpected size %d\n", size);
811 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
812 if (size == sizeof(buf))
813 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
814 /* By getting the hash, further updates are not allowed */
815 SetLastError(0xdeadbeef);
816 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
817 ok(!ret &&
818 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
819 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
820 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */),
821 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
823 /* Even after a final update, the hash data aren't available */
824 SetLastError(0xdeadbeef);
825 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
826 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
827 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
828 /* The version is also available, and should be zero for this message. */
829 size = 0;
830 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
831 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
832 size = sizeof(value);
833 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
834 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
835 ok(value == 0, "Expected version 0, got %d\n", value);
836 /* As usual, the type isn't available. */
837 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
838 ok(!ret, "Expected failure\n");
839 CryptMsgClose(msg);
841 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
842 NULL, &streamInfo);
843 /* Streamed messages don't allow you to get the content or bare content. */
844 SetLastError(0xdeadbeef);
845 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
846 ok(!ret && GetLastError() == E_INVALIDARG,
847 "Expected E_INVALIDARG, got %x\n", GetLastError());
848 SetLastError(0xdeadbeef);
849 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
850 ok(!ret && GetLastError() == E_INVALIDARG,
851 "Expected E_INVALIDARG, got %x\n", GetLastError());
852 /* The hash is still available. */
853 size = 0;
854 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
855 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
856 ok(size == sizeof(buf), "Unexpected size %d\n", size);
857 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
858 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
859 if (size == sizeof(buf))
860 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
861 /* After updating the hash, further updates aren't allowed on streamed
862 * messages either.
864 SetLastError(0xdeadbeef);
865 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
866 ok(!ret &&
867 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
868 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
869 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */),
870 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
872 CryptMsgClose(msg);
875 static const BYTE hashEmptyBareContent[] = {
876 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
877 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
878 static const BYTE hashEmptyContent[] = {
879 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
880 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
881 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
882 static const BYTE hashBareContent[] = {
883 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
884 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
885 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
886 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
887 static const BYTE hashContent[] = {
888 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
889 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
890 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
891 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
892 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
894 static const BYTE detachedHashNonFinalBareContent[] = {
895 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
896 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
897 0x07,0x01,0x04,0x00 };
898 static const BYTE detachedHashNonFinalContent[] = {
899 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
900 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
901 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
902 0x07,0x01,0x04,0x00 };
903 static const BYTE detachedHashBareContent[] = {
904 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
905 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
906 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
907 0x9d,0x2a,0x8f,0x26,0x2f };
908 static const BYTE detachedHashContent[] = {
909 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
910 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
911 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
912 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
913 0x9d,0x2a,0x8f,0x26,0x2f };
915 static void test_hash_msg_encoding(void)
917 HCRYPTMSG msg;
918 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
919 BOOL ret;
920 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
921 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
923 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
924 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
925 NULL, NULL);
926 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
927 hashEmptyBareContent, sizeof(hashEmptyBareContent));
928 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
929 hashEmptyContent, sizeof(hashEmptyContent));
930 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
931 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
932 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
933 hashBareContent, sizeof(hashBareContent));
934 check_param("hash content", msg, CMSG_CONTENT_PARAM,
935 hashContent, sizeof(hashContent));
936 CryptMsgClose(msg);
937 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
938 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
939 CMSG_HASHED, &hashInfo, NULL, NULL);
940 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
941 hashEmptyBareContent, sizeof(hashEmptyBareContent));
942 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
943 hashEmptyContent, sizeof(hashEmptyContent));
944 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
945 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
946 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
947 hashBareContent, sizeof(hashBareContent));
948 check_param("hash content", msg, CMSG_CONTENT_PARAM,
949 hashContent, sizeof(hashContent));
950 CryptMsgClose(msg);
951 /* Same test, but with CMSG_DETACHED_FLAG set */
952 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
953 CMSG_HASHED, &hashInfo, NULL, NULL);
954 check_param("detached hash empty bare content", msg,
955 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
956 sizeof(hashEmptyBareContent));
957 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
958 hashEmptyContent, sizeof(hashEmptyContent));
959 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
960 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
961 check_param("detached hash not final bare content", msg,
962 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
963 sizeof(detachedHashNonFinalBareContent));
964 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
965 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
966 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
967 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
968 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
969 detachedHashBareContent, sizeof(detachedHashBareContent));
970 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
971 detachedHashContent, sizeof(detachedHashContent));
972 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
973 detachedHashBareContent, sizeof(detachedHashBareContent));
974 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
975 detachedHashContent, sizeof(detachedHashContent));
976 CryptMsgClose(msg);
977 /* In what appears to be a bug, streamed updates to hash messages don't
978 * call the output function.
980 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
981 NULL, &streamInfo);
982 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
983 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
984 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
985 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
986 CryptMsgClose(msg);
987 check_updates("empty hash message", &empty_accum, &accum);
988 free_updates(&accum);
990 streamInfo.cbContent = sizeof(msgData);
991 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
992 NULL, &streamInfo);
993 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
994 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
995 CryptMsgClose(msg);
996 check_updates("hash message", &empty_accum, &accum);
997 free_updates(&accum);
999 streamInfo.cbContent = sizeof(msgData);
1000 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
1001 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
1002 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1003 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1004 CryptMsgClose(msg);
1005 check_updates("detached hash message", &empty_accum, &accum);
1006 free_updates(&accum);
1009 static void test_hash_msg(void)
1011 test_hash_msg_open();
1012 test_hash_msg_update();
1013 test_hash_msg_get_param();
1014 test_hash_msg_encoding();
1017 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1018 'm','p',0 };
1019 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1020 'm','p',0 };
1021 static BYTE serialNum[] = { 1 };
1022 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1023 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1025 static void test_signed_msg_open(void)
1027 HCRYPTMSG msg;
1028 BOOL ret;
1029 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1030 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1031 CERT_INFO certInfo = { 0 };
1033 SetLastError(0xdeadbeef);
1034 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1035 NULL, NULL);
1036 ok(!msg && GetLastError() == E_INVALIDARG,
1037 "Expected E_INVALIDARG, got %x\n", GetLastError());
1038 signInfo.cbSize = sizeof(signInfo);
1039 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1040 NULL, NULL);
1041 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1042 CryptMsgClose(msg);
1044 signInfo.cSigners = 1;
1045 signInfo.rgSigners = &signer;
1046 /* With signer.pCertInfo unset, attempting to open this message this
1047 * crashes.
1049 signer.pCertInfo = &certInfo;
1050 /* The cert info must contain a serial number and an issuer. */
1051 SetLastError(0xdeadbeef);
1052 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1053 NULL, NULL);
1054 /* NT: E_INVALIDARG, 9x: unchanged */
1055 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef),
1056 "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError());
1058 certInfo.SerialNumber.cbData = sizeof(serialNum);
1059 certInfo.SerialNumber.pbData = serialNum;
1060 SetLastError(0xdeadbeef);
1061 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1062 NULL, NULL);
1063 /* NT: E_INVALIDARG, 9x: unchanged */
1064 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef),
1065 "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError());
1067 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1068 certInfo.Issuer.pbData = encodedCommonName;
1069 SetLastError(0xdeadbeef);
1070 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1071 NULL, NULL);
1072 ok(!msg && GetLastError() == E_INVALIDARG,
1073 "Expected E_INVALIDARG, got %x\n", GetLastError());
1075 /* The signer's hCryptProv must be set to something. Whether it's usable
1076 * or not will be checked after the hash algorithm is checked (see next
1077 * test.)
1079 signer.hCryptProv = 1;
1080 SetLastError(0xdeadbeef);
1081 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1082 NULL, NULL);
1083 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1084 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1085 /* The signer's hash algorithm must also be set. */
1086 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1087 SetLastError(0xdeadbeef);
1088 /* Crashes in advapi32 in wine, don't do it */
1089 if (0) {
1090 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1091 &signInfo, NULL, NULL);
1092 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1093 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1095 /* The signer's hCryptProv must also be valid. */
1096 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1097 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1098 if (!ret && GetLastError() == NTE_EXISTS) {
1099 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1100 PROV_RSA_FULL, 0);
1102 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1104 if (ret) {
1105 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1106 NULL, NULL);
1107 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1108 CryptMsgClose(msg);
1111 /* pCertInfo must still be set, but can be empty if the SignerId's issuer
1112 * and serial number are set.
1114 certInfo.Issuer.cbData = 0;
1115 certInfo.SerialNumber.cbData = 0;
1116 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1117 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1118 sizeof(encodedCommonName);
1119 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1120 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1121 sizeof(serialNum);
1122 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1123 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1124 NULL, NULL);
1125 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1126 CryptMsgClose(msg);
1128 CryptReleaseContext(signer.hCryptProv, 0);
1129 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1130 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1133 static const BYTE privKey[] = {
1134 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1135 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1136 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1137 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1138 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1139 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1140 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1141 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1142 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1143 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1144 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1145 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1146 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1147 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1148 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1149 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1150 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1151 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1152 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1153 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1154 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1155 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1156 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1157 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1158 static BYTE pubKey[] = {
1159 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1160 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1161 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1162 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1163 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1165 static void test_signed_msg_update(void)
1167 HCRYPTMSG msg;
1168 BOOL ret;
1169 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1170 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1171 CERT_INFO certInfo = { 0 };
1172 HCRYPTKEY key;
1174 certInfo.SerialNumber.cbData = sizeof(serialNum);
1175 certInfo.SerialNumber.pbData = serialNum;
1176 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1177 certInfo.Issuer.pbData = encodedCommonName;
1178 signer.pCertInfo = &certInfo;
1179 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1180 signInfo.cSigners = 1;
1181 signInfo.rgSigners = &signer;
1183 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1184 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1185 if (!ret && GetLastError() == NTE_EXISTS) {
1186 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1187 PROV_RSA_FULL, 0);
1189 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1191 if (!ret) {
1192 skip("No context for tests\n");
1193 return;
1196 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1197 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1198 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1199 /* Detached CMSG_SIGNED allows non-final updates. */
1200 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1201 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1202 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1203 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1204 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1205 /* The final update requires a private key in the hCryptProv, in order to
1206 * generate the signature.
1208 SetLastError(0xdeadbeef);
1209 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1210 ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1211 GetLastError() == NTE_NO_KEY),
1212 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1213 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1214 0, 0, &key);
1215 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1216 /* The final update should be able to succeed now that a key exists, but
1217 * the previous (invalid) final update prevents it.
1219 SetLastError(0xdeadbeef);
1220 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1221 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1222 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1223 CryptMsgClose(msg);
1225 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1226 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1227 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1228 /* Detached CMSG_SIGNED allows non-final updates. */
1229 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1230 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1231 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1232 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1233 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1234 /* Now that the private key exists, the final update can succeed (even
1235 * with no data.)
1237 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1238 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1239 /* But no updates are allowed after the final update. */
1240 SetLastError(0xdeadbeef);
1241 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1242 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1243 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1244 SetLastError(0xdeadbeef);
1245 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1246 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1247 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1248 CryptMsgClose(msg);
1250 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1251 NULL, NULL);
1252 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1253 /* Non-detached messages don't allow non-final updates.. */
1254 SetLastError(0xdeadbeef);
1255 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1256 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1257 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1258 /* but they do allow final ones. */
1259 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1260 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1261 CryptMsgClose(msg);
1262 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1263 NULL, NULL);
1264 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1265 /* They also allow final updates with no data. */
1266 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1267 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1268 CryptMsgClose(msg);
1270 CryptDestroyKey(key);
1271 CryptReleaseContext(signer.hCryptProv, 0);
1272 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1273 CRYPT_DELETEKEYSET);
1276 static const BYTE signedEmptyBareContent[] = {
1277 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1278 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1279 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1280 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1281 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1282 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1283 static const BYTE signedEmptyContent[] = {
1284 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1285 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1286 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1287 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1288 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1289 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1290 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1291 static const BYTE detachedSignedBareContent[] = {
1292 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1293 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1294 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1295 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1296 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1297 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1298 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1299 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1300 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1301 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1302 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1303 static const BYTE detachedSignedContent[] = {
1304 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1305 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1306 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1307 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1308 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1309 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1310 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1311 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1312 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1313 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1314 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1315 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1316 static const BYTE signedBareContent[] = {
1317 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1318 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1319 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1320 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1321 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1322 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1323 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1324 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1325 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1326 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1327 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1328 static const BYTE signedContent[] = {
1329 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1330 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1331 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1332 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1333 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1334 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1335 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1336 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1337 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1338 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1339 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1340 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1341 0x0d };
1342 static const BYTE signedHash[] = {
1343 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1344 0x2f };
1345 static const BYTE signedKeyIdEmptyContent[] = {
1346 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
1347 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1348 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
1349 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1350 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1351 static const BYTE signedEncodedSigner[] = {
1352 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1353 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1354 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1355 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1356 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1357 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1358 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1359 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1360 static const BYTE signedWithAuthAttrsBareContent[] = {
1361 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1362 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1363 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1364 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1365 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1366 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1367 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1368 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1369 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1370 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1371 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1372 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1373 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1374 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1375 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1376 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1377 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1378 0xff,0xc6,0x33,0x63,0x34 };
1379 static BYTE cert[] = {
1380 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1381 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1382 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1383 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1384 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1385 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1386 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1387 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1388 0xff,0x02,0x01,0x01 };
1389 static BYTE v1CertWithPubKey[] = {
1390 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1391 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1392 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1393 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1394 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1395 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1396 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1397 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1398 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1399 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1400 0x01,0x01 };
1401 static const BYTE signedWithCertEmptyBareContent[] = {
1402 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1403 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1404 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1405 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1406 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1407 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1408 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1409 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1410 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1411 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1412 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1413 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1414 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1415 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1416 static const BYTE signedWithCertBareContent[] = {
1417 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1418 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1419 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1420 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1421 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1422 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1423 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1424 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1425 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1426 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1427 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1428 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1429 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1430 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1431 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1432 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1433 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1434 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1435 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1436 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1437 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1438 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1439 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1440 0x30,0x30,0x30,0x30,0x5a };
1441 static const BYTE signedWithCrlEmptyBareContent[] = {
1442 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1443 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1444 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1445 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1446 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1447 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1448 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1449 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1450 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1451 static const BYTE signedWithCrlBareContent[] = {
1452 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1453 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1454 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1455 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1456 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1457 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1458 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1459 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1460 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1461 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1462 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1463 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1464 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1465 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1466 0xa8,0x0d };
1467 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1468 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1469 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1470 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1471 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1472 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1473 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1474 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1475 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1476 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1477 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1478 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1479 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1480 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1481 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1482 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1483 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1484 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1485 0x04,0x00 };
1486 static const BYTE signedWithCertAndCrlBareContent[] = {
1487 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1488 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1489 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1490 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1491 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1492 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1493 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1494 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1495 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1496 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1497 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1498 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1499 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1500 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1501 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1502 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1503 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1504 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1505 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1506 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1507 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1508 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1509 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1510 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1511 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1512 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1513 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1514 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1515 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1516 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1517 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1518 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1519 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1520 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1521 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1522 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1523 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1524 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1525 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1526 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1527 static BYTE v1CertWithValidPubKey[] = {
1528 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1529 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1530 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1531 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1532 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1533 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1534 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1535 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1536 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1537 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1538 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1539 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1540 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1541 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1542 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1543 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1544 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1545 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1546 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1547 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1548 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1549 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1550 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1551 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1552 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1553 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1554 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1555 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1556 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1557 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1558 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1559 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1560 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1561 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1562 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1563 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1564 0x00 };
1565 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1566 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1567 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1568 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1569 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1570 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1571 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1572 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1573 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1574 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1575 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1576 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1577 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1578 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1579 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1580 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1581 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1582 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1583 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1584 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1585 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1586 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1587 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1588 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1589 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1590 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1591 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1592 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1594 static void test_signed_msg_encoding(void)
1596 HCRYPTMSG msg;
1597 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1598 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1599 CERT_INFO certInfo = { 0 };
1600 CERT_BLOB encodedCert = { sizeof(cert), cert };
1601 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1602 char oid_common_name[] = szOID_COMMON_NAME;
1603 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1604 encodedCommonName };
1605 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1606 BOOL ret;
1607 HCRYPTKEY key;
1608 DWORD size;
1610 certInfo.SerialNumber.cbData = sizeof(serialNum);
1611 certInfo.SerialNumber.pbData = serialNum;
1612 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1613 certInfo.Issuer.pbData = encodedCommonName;
1614 signer.pCertInfo = &certInfo;
1615 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1616 signInfo.cSigners = 1;
1617 signInfo.rgSigners = &signer;
1619 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1620 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1621 if (!ret && GetLastError() == NTE_EXISTS) {
1622 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1623 PROV_RSA_FULL, 0);
1625 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1627 if (!ret) {
1628 skip("No context for tests\n");
1629 return;
1632 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1633 0, 0, &key);
1634 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1636 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1637 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1638 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1640 check_param("detached signed empty bare content", msg,
1641 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1642 sizeof(signedEmptyBareContent));
1643 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1644 signedEmptyContent, sizeof(signedEmptyContent));
1645 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1646 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1647 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1648 signedHash, sizeof(signedHash));
1649 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1650 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1651 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1652 detachedSignedContent, sizeof(detachedSignedContent));
1653 SetLastError(0xdeadbeef);
1654 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1655 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1656 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1657 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1658 signedEncodedSigner, sizeof(signedEncodedSigner));
1660 CryptMsgClose(msg);
1662 certInfo.SerialNumber.cbData = 0;
1663 certInfo.Issuer.cbData = 0;
1664 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1665 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1666 U(signer.SignerId).KeyId.pbData = serialNum;
1667 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1668 NULL, NULL);
1669 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1670 check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM,
1671 signedKeyIdEmptyContent, sizeof(signedKeyIdEmptyContent));
1672 CryptMsgClose(msg);
1674 certInfo.SerialNumber.cbData = sizeof(serialNum);
1675 certInfo.SerialNumber.pbData = serialNum;
1676 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1677 certInfo.Issuer.pbData = encodedCommonName;
1678 signer.SignerId.dwIdChoice = 0;
1679 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1680 NULL, NULL);
1681 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1683 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1684 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1685 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1686 signedEmptyContent, sizeof(signedEmptyContent));
1687 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1688 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1689 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1690 signedBareContent, sizeof(signedBareContent));
1691 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1692 signedContent, sizeof(signedContent));
1694 CryptMsgClose(msg);
1696 signer.cAuthAttr = 1;
1697 signer.rgAuthAttr = &attr;
1698 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1699 NULL, NULL);
1700 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1702 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1703 check_param("signed with auth attrs bare content", msg,
1704 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1705 sizeof(signedWithAuthAttrsBareContent));
1707 CryptMsgClose(msg);
1709 signer.cAuthAttr = 0;
1710 signInfo.rgCertEncoded = &encodedCert;
1711 signInfo.cCertEncoded = 1;
1712 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1713 NULL, NULL);
1714 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1716 check_param("signed with cert empty bare content", msg,
1717 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1718 sizeof(signedWithCertEmptyBareContent));
1719 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1720 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1721 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1722 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1724 CryptMsgClose(msg);
1726 signInfo.cCertEncoded = 0;
1727 signInfo.rgCrlEncoded = &encodedCrl;
1728 signInfo.cCrlEncoded = 1;
1729 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1730 NULL, NULL);
1731 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1733 check_param("signed with crl empty bare content", msg,
1734 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1735 sizeof(signedWithCrlEmptyBareContent));
1736 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1737 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1738 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1739 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1741 CryptMsgClose(msg);
1743 signInfo.cCertEncoded = 1;
1744 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1745 NULL, NULL);
1746 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1748 check_param("signed with cert and crl empty bare content", msg,
1749 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1750 sizeof(signedWithCertAndCrlEmptyBareContent));
1751 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1752 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1753 check_param("signed with cert and crl bare content", msg,
1754 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1755 sizeof(signedWithCertAndCrlBareContent));
1757 CryptMsgClose(msg);
1759 /* Test with a cert with a (bogus) public key */
1760 signInfo.cCrlEncoded = 0;
1761 encodedCert.cbData = sizeof(v1CertWithPubKey);
1762 encodedCert.pbData = v1CertWithPubKey;
1763 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1764 NULL, NULL);
1765 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1766 check_param("signedWithCertWithPubKeyBareContent", msg,
1767 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1768 sizeof(signedWithCertWithPubKeyBareContent));
1769 CryptMsgClose(msg);
1771 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1772 encodedCert.pbData = v1CertWithValidPubKey;
1773 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1774 NULL, NULL);
1775 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1776 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1777 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1778 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1779 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1780 check_param("signedWithCertWithValidPubKeyContent", msg,
1781 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1782 sizeof(signedWithCertWithValidPubKeyContent));
1783 CryptMsgClose(msg);
1785 CryptDestroyKey(key);
1786 CryptReleaseContext(signer.hCryptProv, 0);
1787 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1788 CRYPT_DELETEKEYSET);
1791 static void test_signed_msg_get_param(void)
1793 BOOL ret;
1794 HCRYPTMSG msg;
1795 DWORD size, value = 0;
1796 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1797 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1798 CERT_INFO certInfo = { 0 };
1800 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1801 NULL, NULL);
1802 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1804 /* Content and bare content are always gettable */
1805 size = 0;
1806 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1807 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1808 size = 0;
1809 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1810 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1811 /* For "signed" messages, so is the version. */
1812 size = 0;
1813 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1814 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1815 size = sizeof(value);
1816 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1817 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1818 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1819 /* But for this message, with no signers, the hash and signer aren't
1820 * available.
1822 size = 0;
1823 SetLastError(0xdeadbeef);
1824 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1825 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1826 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1827 SetLastError(0xdeadbeef);
1828 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1829 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1830 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1831 /* As usual, the type isn't available. */
1832 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1833 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1834 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1836 CryptMsgClose(msg);
1838 certInfo.SerialNumber.cbData = sizeof(serialNum);
1839 certInfo.SerialNumber.pbData = serialNum;
1840 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1841 certInfo.Issuer.pbData = encodedCommonName;
1842 signer.pCertInfo = &certInfo;
1843 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1844 signInfo.cSigners = 1;
1845 signInfo.rgSigners = &signer;
1847 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1848 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1849 if (!ret && GetLastError() == NTE_EXISTS) {
1850 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1851 PROV_RSA_FULL, 0);
1853 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1855 if (!ret) {
1856 skip("No context for tests\n");
1857 return;
1860 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1861 NULL, NULL);
1862 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1864 /* This message, with one signer, has the hash and signer for index 0
1865 * available, but not for other indexes.
1867 size = 0;
1868 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1869 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1870 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1871 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1872 size = 0;
1873 SetLastError(0xdeadbeef);
1874 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1875 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1876 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1877 SetLastError(0xdeadbeef);
1878 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1879 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1880 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1881 /* As usual, the type isn't available. */
1882 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1883 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1884 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1886 CryptMsgClose(msg);
1888 /* Opening the message using the CMS fields.. */
1889 certInfo.SerialNumber.cbData = 0;
1890 certInfo.Issuer.cbData = 0;
1891 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1892 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1893 sizeof(encodedCommonName);
1894 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1895 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1896 sizeof(serialNum);
1897 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1898 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1899 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1900 if (!ret && GetLastError() == NTE_EXISTS)
1901 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1902 PROV_RSA_FULL, 0);
1903 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1904 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1905 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1906 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1907 /* still results in the version being 1 when the issuer and serial number
1908 * are used and no additional CMS fields are used.
1910 size = sizeof(value);
1911 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1912 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1913 ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value);
1914 /* Apparently the encoded signer can be retrieved.. */
1915 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1916 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1917 /* but the signer info, CMS signer info, and cert ID can't be. */
1918 SetLastError(0xdeadbeef);
1919 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1920 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1921 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1922 SetLastError(0xdeadbeef);
1923 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1924 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1925 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1926 SetLastError(0xdeadbeef);
1927 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1928 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1929 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1930 CryptMsgClose(msg);
1932 /* Using the KeyId field of the SignerId results in the version becoming
1933 * the CMS version.
1935 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1936 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1937 U(signer.SignerId).KeyId.pbData = serialNum;
1938 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1939 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1940 if (!ret && GetLastError() == NTE_EXISTS)
1941 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1942 PROV_RSA_FULL, 0);
1943 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1944 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1945 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1946 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1947 size = sizeof(value);
1948 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1949 ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value);
1950 /* Even for a CMS message, the signer can be retrieved.. */
1951 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1952 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1953 /* but the signer info, CMS signer info, and cert ID can't be. */
1954 SetLastError(0xdeadbeef);
1955 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1956 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1957 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1958 SetLastError(0xdeadbeef);
1959 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1960 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1961 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1962 SetLastError(0xdeadbeef);
1963 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1964 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1965 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1966 CryptMsgClose(msg);
1968 CryptReleaseContext(signer.hCryptProv, 0);
1969 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1970 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1973 static void test_signed_msg(void)
1975 test_signed_msg_open();
1976 test_signed_msg_update();
1977 test_signed_msg_encoding();
1978 test_signed_msg_get_param();
1981 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1982 static const struct update_accum a4 = { 1, &b4 };
1984 static const BYTE bogusOIDContent[] = {
1985 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1986 0x04,0x00 };
1987 static const BYTE bogusHashContent[] = {
1988 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1989 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1990 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1991 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1992 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1994 static void test_decode_msg_update(void)
1996 HCRYPTMSG msg;
1997 BOOL ret;
1998 CMSG_STREAM_INFO streamInfo = { 0 };
1999 DWORD i;
2000 struct update_accum accum = { 0, NULL };
2002 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2003 /* Update with a full message in a final update */
2004 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2005 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2006 /* Can't update after a final update */
2007 SetLastError(0xdeadbeef);
2008 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2009 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2010 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2011 CryptMsgClose(msg);
2013 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2014 /* Can't send a non-final update without streaming */
2015 SetLastError(0xdeadbeef);
2016 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2017 FALSE);
2018 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2019 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2020 /* A subsequent final update succeeds */
2021 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2022 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2023 CryptMsgClose(msg);
2025 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2026 /* Updating a message that has a NULL stream callback fails */
2027 SetLastError(0xdeadbeef);
2028 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2029 FALSE);
2030 todo_wine
2031 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2032 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2033 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2034 GetLastError());
2035 /* Changing the callback pointer after the fact yields the same error (so
2036 * the message must copy the stream info, not just store a pointer to it)
2038 streamInfo.pfnStreamOutput = nop_stream_output;
2039 SetLastError(0xdeadbeef);
2040 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2041 FALSE);
2042 todo_wine
2043 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2044 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2045 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2046 GetLastError());
2047 CryptMsgClose(msg);
2049 /* Empty non-final updates are allowed when streaming.. */
2050 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2051 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2052 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2053 /* but final updates aren't when not enough data has been received. */
2054 SetLastError(0xdeadbeef);
2055 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2056 todo_wine
2057 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2058 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2059 CryptMsgClose(msg);
2061 /* Updating the message byte by byte is legal */
2062 streamInfo.pfnStreamOutput = accumulating_stream_output;
2063 streamInfo.pvArg = &accum;
2064 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2065 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2066 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2067 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2068 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2069 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2070 CryptMsgClose(msg);
2071 todo_wine
2072 check_updates("byte-by-byte empty content", &a4, &accum);
2073 free_updates(&accum);
2075 /* Decoding bogus content fails in non-streaming mode.. */
2076 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2077 SetLastError(0xdeadbeef);
2078 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2079 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2080 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2081 CryptMsgClose(msg);
2082 /* and as the final update in streaming mode.. */
2083 streamInfo.pfnStreamOutput = nop_stream_output;
2084 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2085 SetLastError(0xdeadbeef);
2086 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2087 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2088 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2089 CryptMsgClose(msg);
2090 /* and even as a non-final update in streaming mode. */
2091 streamInfo.pfnStreamOutput = nop_stream_output;
2092 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2093 SetLastError(0xdeadbeef);
2094 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2095 todo_wine
2096 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2097 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2098 CryptMsgClose(msg);
2100 /* An empty message can be opened with undetermined type.. */
2101 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2102 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2103 TRUE);
2104 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2105 CryptMsgClose(msg);
2106 /* but decoding it as an explicitly typed message fails. */
2107 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2108 NULL);
2109 SetLastError(0xdeadbeef);
2110 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2111 TRUE);
2112 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2113 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2114 CryptMsgClose(msg);
2115 /* On the other hand, decoding the bare content of an empty message fails
2116 * with unspecified type..
2118 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2119 SetLastError(0xdeadbeef);
2120 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2121 sizeof(dataEmptyBareContent), TRUE);
2122 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2123 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2124 CryptMsgClose(msg);
2125 /* but succeeds with explicit type. */
2126 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2127 NULL);
2128 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2129 sizeof(dataEmptyBareContent), TRUE);
2130 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2131 CryptMsgClose(msg);
2133 /* Decoding valid content with an unsupported OID fails */
2134 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2135 SetLastError(0xdeadbeef);
2136 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2137 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2138 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2139 CryptMsgClose(msg);
2141 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2142 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2143 SetLastError(0xdeadbeef);
2144 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2145 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2146 CryptMsgClose(msg);
2147 /* while with specified type it fails. */
2148 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2149 NULL);
2150 SetLastError(0xdeadbeef);
2151 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2152 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2153 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2154 CryptMsgClose(msg);
2155 /* On the other hand, decoding the bare content of an empty hash message
2156 * fails with unspecified type..
2158 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2159 SetLastError(0xdeadbeef);
2160 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2161 sizeof(hashEmptyBareContent), TRUE);
2162 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2163 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2164 CryptMsgClose(msg);
2165 /* but succeeds with explicit type. */
2166 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2167 NULL);
2168 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2169 sizeof(hashEmptyBareContent), TRUE);
2170 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2171 CryptMsgClose(msg);
2173 /* And again, opening a (non-empty) hash message with unspecified type
2174 * succeeds..
2176 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2177 SetLastError(0xdeadbeef);
2178 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2179 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2180 CryptMsgClose(msg);
2181 /* while with specified type it fails.. */
2182 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2183 NULL);
2184 SetLastError(0xdeadbeef);
2185 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2186 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2187 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2188 CryptMsgClose(msg);
2189 /* and decoding the bare content of a non-empty hash message fails with
2190 * unspecified type..
2192 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2193 SetLastError(0xdeadbeef);
2194 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2195 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2196 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2197 CryptMsgClose(msg);
2198 /* but succeeds with explicit type. */
2199 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2200 NULL);
2201 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2202 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2203 CryptMsgClose(msg);
2205 /* Opening a (non-empty) hash message with unspecified type and a bogus
2206 * hash value succeeds..
2208 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2209 SetLastError(0xdeadbeef);
2210 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2211 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2212 CryptMsgClose(msg);
2214 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2215 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2216 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2217 CryptMsgClose(msg);
2218 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2219 SetLastError(0xdeadbeef);
2220 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2221 sizeof(signedWithCertAndCrlBareContent), TRUE);
2222 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2223 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2224 CryptMsgClose(msg);
2225 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2226 NULL);
2227 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2228 sizeof(signedWithCertAndCrlBareContent), TRUE);
2229 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2230 CryptMsgClose(msg);
2232 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2233 NULL, NULL);
2234 /* The first update succeeds.. */
2235 ret = CryptMsgUpdate(msg, detachedSignedContent,
2236 sizeof(detachedSignedContent), TRUE);
2237 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2238 /* as does a second (probably to update the detached portion).. */
2239 ret = CryptMsgUpdate(msg, detachedSignedContent,
2240 sizeof(detachedSignedContent), TRUE);
2241 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2242 /* while a third fails. */
2243 ret = CryptMsgUpdate(msg, detachedSignedContent,
2244 sizeof(detachedSignedContent), TRUE);
2245 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2246 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2247 CryptMsgClose(msg);
2249 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2250 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2251 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2252 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2253 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2254 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2255 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2256 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2257 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2259 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2260 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2261 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2262 CryptMsgClose(msg);
2265 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2266 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2268 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2269 const CMSG_SIGNER_INFO *expected)
2271 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2272 expected->dwVersion, got->dwVersion);
2273 ok(got->Issuer.cbData == expected->Issuer.cbData,
2274 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2275 got->Issuer.cbData);
2276 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2277 "Unexpected issuer\n");
2278 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2279 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2280 got->SerialNumber.cbData);
2281 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2282 got->SerialNumber.cbData), "Unexpected serial number\n");
2283 /* FIXME: check more things */
2286 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2287 const CMSG_CMS_SIGNER_INFO *expected)
2289 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2290 expected->dwVersion, got->dwVersion);
2291 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2292 "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2293 got->SignerId.dwIdChoice);
2294 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2296 if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2298 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2299 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2300 "Expected issuer size %d, got %d\n",
2301 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2302 U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2303 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2304 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2305 U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2306 "Unexpected issuer\n");
2307 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2308 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2309 "Expected serial number size %d, got %d\n",
2310 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2311 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2312 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2313 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2314 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2315 "Unexpected serial number\n");
2317 else
2319 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2320 "expected key id size %d, got %d\n",
2321 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2322 ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2323 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2324 "unexpected key id\n");
2327 /* FIXME: check more things */
2330 static const BYTE signedWithCertAndCrlComputedHash[] = {
2331 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2332 0x2f };
2333 static BYTE keyIdIssuer[] = {
2334 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2335 0x0a,0x07,0x01,0x04,0x01,0x01 };
2337 static void test_decode_msg_get_param(void)
2339 HCRYPTMSG msg;
2340 BOOL ret;
2341 DWORD size = 0, value;
2342 LPBYTE buf;
2344 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2345 SetLastError(0xdeadbeef);
2346 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2347 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2348 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2349 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2350 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2351 sizeof(msgData));
2352 CryptMsgClose(msg);
2354 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2355 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2356 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2357 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2358 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2359 emptyHashParam, sizeof(emptyHashParam));
2360 CryptMsgClose(msg);
2361 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2362 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2363 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2364 sizeof(msgData));
2365 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2366 sizeof(hashParam));
2367 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2368 hashParam, sizeof(hashParam));
2369 /* Curiously, getting the hash of index 1 succeeds, even though there's
2370 * only one hash.
2372 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2373 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2374 buf = CryptMemAlloc(size);
2375 if (buf)
2377 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2378 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2379 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2380 CryptMemFree(buf);
2382 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2383 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2384 value = CMSG_HASHED_DATA_V0;
2385 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2386 sizeof(value));
2387 CryptMsgClose(msg);
2389 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2390 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2391 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2392 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2393 sizeof(msgData));
2394 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2395 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2396 size = sizeof(value);
2397 value = 2112;
2398 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2399 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2400 ok(value == 1, "Expected 1 signer, got %d\n", value);
2401 size = 0;
2402 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2403 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2404 if (ret)
2405 buf = CryptMemAlloc(size);
2406 else
2407 buf = NULL;
2408 if (buf)
2410 CMSG_SIGNER_INFO signer = { 0 };
2412 signer.dwVersion = 1;
2413 signer.Issuer.cbData = sizeof(encodedCommonName);
2414 signer.Issuer.pbData = encodedCommonName;
2415 signer.SerialNumber.cbData = sizeof(serialNum);
2416 signer.SerialNumber.pbData = serialNum;
2417 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2418 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2419 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2420 CryptMemFree(buf);
2422 /* Getting the CMS signer info of a PKCS7 message is possible. */
2423 size = 0;
2424 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2425 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2426 if (ret)
2427 buf = CryptMemAlloc(size);
2428 else
2429 buf = NULL;
2430 if (buf)
2432 CMSG_CMS_SIGNER_INFO signer = { 0 };
2434 signer.dwVersion = 1;
2435 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2436 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2437 sizeof(encodedCommonName);
2438 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2439 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2440 sizeof(serialNum);
2441 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2442 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2443 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2444 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2445 CryptMemFree(buf);
2447 /* index is ignored when getting signer count */
2448 size = sizeof(value);
2449 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2450 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2451 ok(value == 1, "Expected 1 signer, got %d\n", value);
2452 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2453 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2454 ok(value == 0, "Expected 0 certs, got %d\n", value);
2455 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2456 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2457 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2458 CryptMsgClose(msg);
2459 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2460 NULL);
2461 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2462 sizeof(signedWithCertAndCrlBareContent), TRUE);
2463 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2464 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2465 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2466 ok(value == 1, "Expected 1 cert, got %d\n", value);
2467 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2468 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2469 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2470 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2471 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2472 check_param("signed with cert and CRL computed hash", msg,
2473 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2474 sizeof(signedWithCertAndCrlComputedHash));
2475 CryptMsgClose(msg);
2477 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2478 ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
2479 sizeof(signedKeyIdEmptyContent), TRUE);
2480 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2481 size = sizeof(value);
2482 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2483 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2484 ok(value == 1, "Expected 1 signer, got %d\n", value);
2485 /* Getting the regular (non-CMS) signer info from a CMS message is also
2486 * possible..
2488 size = 0;
2489 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2490 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2491 if (ret)
2492 buf = CryptMemAlloc(size);
2493 else
2494 buf = NULL;
2495 if (buf)
2497 CMSG_SIGNER_INFO signer;
2498 BYTE zero = 0;
2500 /* and here's the little oddity: for a CMS message using the key id
2501 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
2502 * a signer with a zero (not empty) serial number, and whose issuer is
2503 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
2504 * and value of the key id.
2506 signer.dwVersion = CMSG_SIGNED_DATA_V3;
2507 signer.Issuer.cbData = sizeof(keyIdIssuer);
2508 signer.Issuer.pbData = keyIdIssuer;
2509 signer.SerialNumber.cbData = 1;
2510 signer.SerialNumber.pbData = &zero;
2511 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2512 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2513 CryptMemFree(buf);
2515 size = 0;
2516 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2517 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2518 if (ret)
2519 buf = CryptMemAlloc(size);
2520 else
2521 buf = NULL;
2522 if (buf)
2524 CMSG_CMS_SIGNER_INFO signer = { 0 };
2526 signer.dwVersion = CMSG_SIGNED_DATA_V3;
2527 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2528 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
2529 U(signer.SignerId).KeyId.pbData = serialNum;
2530 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2531 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2532 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2533 CryptMemFree(buf);
2535 CryptMsgClose(msg);
2538 static void test_decode_msg(void)
2540 test_decode_msg_update();
2541 test_decode_msg_get_param();
2544 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2545 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2546 static BYTE encodedPubKey[] = {
2547 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2548 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2549 0x0d,0x0e,0x0f };
2550 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2551 static BYTE mod_encoded[] = {
2552 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2553 0x01,0x00,0x01 };
2555 static void test_msg_control(void)
2557 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2558 BOOL ret;
2559 HCRYPTMSG msg;
2560 DWORD i;
2561 CERT_INFO certInfo = { 0 };
2562 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2563 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2564 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2566 /* Crashes
2567 ret = CryptMsgControl(NULL, 0, 0, NULL);
2570 /* Data encode messages don't allow any sort of control.. */
2571 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2572 NULL);
2573 /* either with no prior update.. */
2574 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2576 SetLastError(0xdeadbeef);
2577 ret = CryptMsgControl(msg, 0, i, NULL);
2578 ok(!ret && GetLastError() == E_INVALIDARG,
2579 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2581 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2582 /* or after an update. */
2583 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2585 SetLastError(0xdeadbeef);
2586 ret = CryptMsgControl(msg, 0, i, NULL);
2587 ok(!ret && GetLastError() == E_INVALIDARG,
2588 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2590 CryptMsgClose(msg);
2592 /* Hash encode messages don't allow any sort of control.. */
2593 hashInfo.cbSize = sizeof(hashInfo);
2594 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2595 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2596 NULL, NULL);
2597 /* either with no prior update.. */
2598 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2600 SetLastError(0xdeadbeef);
2601 ret = CryptMsgControl(msg, 0, i, NULL);
2602 ok(!ret && GetLastError() == E_INVALIDARG,
2603 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2605 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2606 /* or after an update. */
2607 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2609 SetLastError(0xdeadbeef);
2610 ret = CryptMsgControl(msg, 0, i, NULL);
2611 ok(!ret && GetLastError() == E_INVALIDARG,
2612 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2614 CryptMsgClose(msg);
2616 /* Signed encode messages likewise don't allow any sort of control.. */
2617 signInfo.cbSize = sizeof(signInfo);
2618 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2619 NULL, NULL);
2620 /* either before an update.. */
2621 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2623 SetLastError(0xdeadbeef);
2624 ret = CryptMsgControl(msg, 0, i, NULL);
2625 ok(!ret && GetLastError() == E_INVALIDARG,
2626 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2628 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2629 /* or after an update. */
2630 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2632 SetLastError(0xdeadbeef);
2633 ret = CryptMsgControl(msg, 0, i, NULL);
2634 ok(!ret && GetLastError() == E_INVALIDARG,
2635 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2637 CryptMsgClose(msg);
2639 /* Decode messages behave a bit differently. */
2640 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2641 /* Bad control type */
2642 SetLastError(0xdeadbeef);
2643 ret = CryptMsgControl(msg, 0, 0, NULL);
2644 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2645 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2646 SetLastError(0xdeadbeef);
2647 ret = CryptMsgControl(msg, 1, 0, NULL);
2648 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2649 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2650 /* Can't verify the hash of an indeterminate-type message */
2651 SetLastError(0xdeadbeef);
2652 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2653 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2654 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2655 /* Crashes
2656 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2658 /* Can't decrypt an indeterminate-type message */
2659 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2660 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2661 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2662 CryptMsgClose(msg);
2664 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2665 NULL);
2666 /* Can't verify the hash of an empty message */
2667 SetLastError(0xdeadbeef);
2668 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2669 todo_wine
2670 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2671 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2672 /* Crashes
2673 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2675 /* Can't verify the signature of a hash message */
2676 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2677 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2678 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2679 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2680 TRUE);
2681 /* Oddly enough, this fails */
2682 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2683 ok(!ret, "Expected failure\n");
2684 CryptMsgClose(msg);
2685 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2686 NULL);
2687 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2688 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2689 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2690 /* Can't decrypt an indeterminate-type message */
2691 SetLastError(0xdeadbeef);
2692 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2693 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2694 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2695 CryptMsgClose(msg);
2697 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2698 NULL, NULL);
2699 /* Can't verify the hash of a detached message before it's been updated. */
2700 SetLastError(0xdeadbeef);
2701 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2702 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2703 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2704 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
2705 TRUE);
2706 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2707 /* Still can't verify the hash of a detached message with the content
2708 * of the detached hash given..
2710 SetLastError(0xdeadbeef);
2711 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2712 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
2713 "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
2714 /* and giving the content of the message after attempting to verify the
2715 * hash fails.
2717 SetLastError(0xdeadbeef);
2718 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2719 todo_wine
2720 ok(!ret &&
2721 (GetLastError() == NTE_BAD_HASH_STATE ||
2722 GetLastError() == NTE_BAD_ALGID || /* Win9x */
2723 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
2724 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
2725 "got %08x\n", GetLastError());
2726 CryptMsgClose(msg);
2728 /* Finally, verifying the hash of a detached message in the correct order:
2729 * 1. Update with the detached hash message
2730 * 2. Update with the content of the message
2731 * 3. Verifying the hash of the message
2732 * succeeds.
2734 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2735 NULL, NULL);
2736 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
2737 TRUE);
2738 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2739 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2740 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2741 SetLastError(0xdeadbeef);
2742 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2743 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2744 CryptMsgClose(msg);
2746 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2747 NULL);
2748 /* Can't verify the hash of a signed message */
2749 SetLastError(0xdeadbeef);
2750 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2751 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2752 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2753 /* Can't decrypt a signed message */
2754 SetLastError(0xdeadbeef);
2755 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2756 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2757 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2758 /* Crash
2759 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2760 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2762 CryptMsgUpdate(msg, signedWithCertBareContent,
2763 sizeof(signedWithCertBareContent), TRUE);
2764 /* With an empty cert info, the signer can't be found in the message (and
2765 * the signature can't be verified.
2767 SetLastError(0xdeadbeef);
2768 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2769 ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2770 "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2771 /* The cert info is expected to have an issuer, serial number, and public
2772 * key info set.
2774 certInfo.SerialNumber.cbData = sizeof(serialNum);
2775 certInfo.SerialNumber.pbData = serialNum;
2776 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2777 certInfo.Issuer.pbData = encodedCommonName;
2778 SetLastError(0xdeadbeef);
2779 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2780 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2781 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2782 CryptMsgClose(msg);
2783 /* This cert has a public key, but it's not in a usable form */
2784 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2785 NULL);
2786 CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2787 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2788 /* Again, cert info needs to have a public key set */
2789 SetLastError(0xdeadbeef);
2790 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2791 ok(!ret &&
2792 (GetLastError() == CRYPT_E_ASN1_EOD ||
2793 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2794 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2795 /* The public key is supposed to be in encoded form.. */
2796 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2797 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2798 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2799 SetLastError(0xdeadbeef);
2800 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2801 ok(!ret &&
2802 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2803 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2804 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2805 /* but not as a X509_PUBLIC_KEY_INFO.. */
2806 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2807 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2808 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2809 SetLastError(0xdeadbeef);
2810 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2811 ok(!ret &&
2812 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2813 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2814 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2815 /* This decodes successfully, but it doesn't match any key in the message */
2816 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2817 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2818 SetLastError(0xdeadbeef);
2819 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2820 /* In Wine's rsaenh, this fails to decode because the key length is too
2821 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
2822 * now.
2824 todo_wine
2825 ok(!ret &&
2826 (GetLastError() == NTE_BAD_SIGNATURE ||
2827 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2828 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2829 CryptMsgClose(msg);
2830 /* A message with no data doesn't have a valid signature */
2831 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2832 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2833 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2834 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2835 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2836 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2837 SetLastError(0xdeadbeef);
2838 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2839 ok(!ret &&
2840 (GetLastError() == NTE_BAD_SIGNATURE ||
2841 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2842 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2843 CryptMsgClose(msg);
2844 /* Finally, this succeeds */
2845 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2846 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2847 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2848 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2849 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2850 CryptMsgClose(msg);
2852 /* Test verifying signature of a detached signed message */
2853 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2854 NULL, NULL);
2855 ret = CryptMsgUpdate(msg, detachedSignedContent,
2856 sizeof(detachedSignedContent), TRUE);
2857 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2858 /* Can't verify the sig without having updated the data */
2859 SetLastError(0xdeadbeef);
2860 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2861 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2862 "expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2863 /* Now that the signature's been checked, can't do the final update */
2864 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2865 todo_wine
2866 ok(!ret &&
2867 (GetLastError() == NTE_BAD_HASH_STATE ||
2868 GetLastError() == NTE_BAD_ALGID || /* Win9x */
2869 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
2870 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
2871 "got %08x\n", GetLastError());
2872 CryptMsgClose(msg);
2873 /* Updating with the detached portion of the message and the data of the
2874 * the message allows the sig to be verified.
2876 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2877 NULL, NULL);
2878 ret = CryptMsgUpdate(msg, detachedSignedContent,
2879 sizeof(detachedSignedContent), TRUE);
2880 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2881 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2882 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2883 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2884 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2885 CryptMsgClose(msg);
2888 /* win9x has much less parameter checks and will crash on many tests
2889 * this code is from test_signed_msg_update()
2891 static BOOL detect_nt(void)
2893 BOOL ret;
2894 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
2895 CERT_INFO certInfo = { 0 };
2897 if (!pCryptAcquireContextW)
2898 return FALSE;
2900 certInfo.SerialNumber.cbData = sizeof(serialNum);
2901 certInfo.SerialNumber.pbData = serialNum;
2902 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2903 certInfo.Issuer.pbData = encodedCommonName;
2904 signer.pCertInfo = &certInfo;
2905 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2907 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2908 PROV_RSA_FULL, CRYPT_NEWKEYSET);
2909 if (!ret && GetLastError() == NTE_EXISTS) {
2910 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2911 PROV_RSA_FULL, 0);
2914 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
2916 /* cleanup */
2917 CryptReleaseContext(signer.hCryptProv, 0);
2918 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
2919 CRYPT_DELETEKEYSET);
2921 return TRUE;
2924 static void test_msg_get_and_verify_signer(void)
2926 BOOL ret;
2927 HCRYPTMSG msg;
2928 PCCERT_CONTEXT signer;
2929 DWORD signerIndex;
2930 HCERTSTORE store;
2932 /* Crash */
2933 if (0)
2935 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
2936 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
2939 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2940 /* An empty message has no signer */
2941 SetLastError(0xdeadbeef);
2942 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2943 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2944 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2945 /* The signer is cleared on error */
2946 signer = (PCCERT_CONTEXT)0xdeadbeef;
2947 SetLastError(0xdeadbeef);
2948 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2949 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2950 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2951 ok(!signer, "expected signer to be NULL\n");
2952 /* The signer index is also cleared on error */
2953 signerIndex = 0xdeadbeef;
2954 SetLastError(0xdeadbeef);
2955 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2956 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2957 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2958 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
2959 /* An unsigned message (msgData isn't a signed message at all)
2960 * likewise has no signer.
2962 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2963 SetLastError(0xdeadbeef);
2964 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2965 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2966 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2967 CryptMsgClose(msg);
2969 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2970 /* A "signed" message created with no signer cert likewise has no signer */
2971 CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
2972 SetLastError(0xdeadbeef);
2973 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2974 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2975 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2976 CryptMsgClose(msg);
2978 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2979 /* A signed message succeeds, .. */
2980 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2981 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2982 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2983 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2984 /* the signer index can be retrieved, .. */
2985 signerIndex = 0xdeadbeef;
2986 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2987 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2988 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
2989 /* as can the signer cert. */
2990 signer = (PCCERT_CONTEXT)0xdeadbeef;
2991 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2992 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2993 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
2994 "expected a valid signer\n");
2995 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
2996 CertFreeCertificateContext(signer);
2997 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
2999 signerIndex = 0xdeadbeef;
3000 SetLastError(0xdeadbeef);
3001 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3002 NULL, &signerIndex);
3003 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3004 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3005 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3006 * message signer not to be found.
3008 SetLastError(0xdeadbeef);
3009 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3010 NULL, NULL);
3011 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3012 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3013 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3014 * the message signer not to be found.
3016 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3017 CERT_STORE_CREATE_NEW_FLAG, NULL);
3018 SetLastError(0xdeadbeef);
3019 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3020 NULL, NULL);
3021 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3022 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3023 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3024 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3025 CERT_STORE_ADD_ALWAYS, NULL);
3026 ok(ret, "CertAddEncodedCertificateToStore failed: 0x%08x\n",
3027 GetLastError());
3028 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3029 * the signer succeeds.
3031 SetLastError(0xdeadbeef);
3032 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3033 NULL, NULL);
3034 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3035 CertCloseStore(store, 0);
3036 CryptMsgClose(msg);
3039 START_TEST(msg)
3041 init_function_pointers();
3042 have_nt = detect_nt();
3044 /* Basic parameter checking tests */
3045 test_msg_open_to_encode();
3046 test_msg_open_to_decode();
3047 test_msg_get_param();
3048 test_msg_close();
3049 test_msg_control();
3051 /* Message-type specific tests */
3052 test_data_msg();
3053 test_hash_msg();
3054 test_signed_msg();
3055 test_decode_msg();
3057 test_msg_get_and_verify_signer();