stash
[wine/wine64.git] / dlls / crypt32 / tests / msg.c
blobe8e7eb317470fa84e4b3527468559d67ea6005f7
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, (LPBYTE)&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, (LPBYTE)&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, (LPBYTE)&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, (LPBYTE)&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, (LPBYTE)&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, (LPBYTE)&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, (LPBYTE)&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, (LPBYTE)&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 =
1120 (BYTE *)encodedCommonName;
1121 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1122 sizeof(serialNum);
1123 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
1124 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1125 NULL, NULL);
1126 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1127 CryptMsgClose(msg);
1129 CryptReleaseContext(signer.hCryptProv, 0);
1130 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1131 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1134 static const BYTE privKey[] = {
1135 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1136 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1137 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1138 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1139 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1140 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1141 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1142 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1143 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1144 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1145 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1146 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1147 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1148 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1149 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1150 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1151 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1152 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1153 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1154 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1155 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1156 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1157 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1158 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1159 static BYTE pubKey[] = {
1160 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1161 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1162 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1163 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1164 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1166 static void test_signed_msg_update(void)
1168 HCRYPTMSG msg;
1169 BOOL ret;
1170 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1171 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1172 CERT_INFO certInfo = { 0 };
1173 HCRYPTKEY key;
1175 certInfo.SerialNumber.cbData = sizeof(serialNum);
1176 certInfo.SerialNumber.pbData = serialNum;
1177 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1178 certInfo.Issuer.pbData = encodedCommonName;
1179 signer.pCertInfo = &certInfo;
1180 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1181 signInfo.cSigners = 1;
1182 signInfo.rgSigners = &signer;
1184 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1185 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1186 if (!ret && GetLastError() == NTE_EXISTS) {
1187 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1188 PROV_RSA_FULL, 0);
1190 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1192 if (!ret) {
1193 skip("No context for tests\n");
1194 return;
1197 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1198 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1199 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1200 /* Detached CMSG_SIGNED allows non-final updates. */
1201 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1202 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1203 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1204 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1205 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1206 /* The final update requires a private key in the hCryptProv, in order to
1207 * generate the signature.
1209 SetLastError(0xdeadbeef);
1210 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1211 ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1212 GetLastError() == NTE_NO_KEY),
1213 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1214 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1215 0, 0, &key);
1216 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1217 /* The final update should be able to succeed now that a key exists, but
1218 * the previous (invalid) final update prevents it.
1220 SetLastError(0xdeadbeef);
1221 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1222 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1223 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1224 CryptMsgClose(msg);
1226 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1227 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1228 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1229 /* Detached CMSG_SIGNED allows non-final updates. */
1230 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1231 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1232 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1233 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1234 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1235 /* Now that the private key exists, the final update can succeed (even
1236 * with no data.)
1238 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1239 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1240 /* But no updates are allowed after the final update. */
1241 SetLastError(0xdeadbeef);
1242 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1243 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1244 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1245 SetLastError(0xdeadbeef);
1246 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1247 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1248 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1249 CryptMsgClose(msg);
1251 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1252 NULL, NULL);
1253 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1254 /* Non-detached messages don't allow non-final updates.. */
1255 SetLastError(0xdeadbeef);
1256 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1257 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1258 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1259 /* but they do allow final ones. */
1260 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1261 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1262 CryptMsgClose(msg);
1263 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1264 NULL, NULL);
1265 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1266 /* They also allow final updates with no data. */
1267 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1268 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1269 CryptMsgClose(msg);
1271 CryptDestroyKey(key);
1272 CryptReleaseContext(signer.hCryptProv, 0);
1273 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1274 CRYPT_DELETEKEYSET);
1277 static const BYTE signedEmptyBareContent[] = {
1278 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1279 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1280 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1281 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1282 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1283 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1284 static const BYTE signedEmptyContent[] = {
1285 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1286 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1287 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1288 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1289 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1290 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1291 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1292 static const BYTE detachedSignedBareContent[] = {
1293 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1294 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1295 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1296 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1297 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1298 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1299 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1300 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1301 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1302 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1303 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1304 static const BYTE detachedSignedContent[] = {
1305 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1306 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1307 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1308 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1309 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1310 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1311 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1312 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1313 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1314 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1315 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1316 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1317 static const BYTE signedBareContent[] = {
1318 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1319 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1320 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1321 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1322 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1323 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1324 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1325 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1326 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1327 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1328 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1329 static const BYTE signedContent[] = {
1330 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1331 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1332 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1333 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1334 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1335 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1336 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1337 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1338 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1339 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1340 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1341 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1342 0x0d };
1343 static const BYTE signedHash[] = {
1344 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1345 0x2f };
1346 static const BYTE signedKeyIdEmptyContent[] = {
1347 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
1348 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1349 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
1350 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1351 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1352 static const BYTE signedEncodedSigner[] = {
1353 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1354 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1355 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1356 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1357 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1358 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1359 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1360 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1361 static const BYTE signedWithAuthAttrsBareContent[] = {
1362 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1363 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1364 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1365 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1366 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1367 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1368 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1369 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1370 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1371 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1372 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1373 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1374 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1375 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1376 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1377 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1378 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1379 0xff,0xc6,0x33,0x63,0x34 };
1380 static BYTE cert[] = {
1381 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1382 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1383 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1384 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1385 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1386 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1387 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1388 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1389 0xff,0x02,0x01,0x01 };
1390 static BYTE v1CertWithPubKey[] = {
1391 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1392 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1393 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1394 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1395 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1396 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1397 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1398 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1399 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1400 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1401 0x01,0x01 };
1402 static const BYTE signedWithCertEmptyBareContent[] = {
1403 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1404 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1405 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1406 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1407 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1408 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1409 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1410 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1411 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1412 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1413 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1414 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1415 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1416 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1417 static const BYTE signedWithCertBareContent[] = {
1418 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1419 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1420 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1421 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1422 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1423 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1424 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1425 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1426 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1427 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1428 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1429 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1430 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1431 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1432 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1433 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1434 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1435 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1436 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1437 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1438 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1439 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1440 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1441 0x30,0x30,0x30,0x30,0x5a };
1442 static const BYTE signedWithCrlEmptyBareContent[] = {
1443 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1444 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1445 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1446 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1447 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1448 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1449 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1450 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1451 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1452 static const BYTE signedWithCrlBareContent[] = {
1453 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1454 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1455 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1456 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1457 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1458 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1459 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1460 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1461 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1462 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1463 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1464 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1465 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1466 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1467 0xa8,0x0d };
1468 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1469 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1470 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1471 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1472 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1473 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1474 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1475 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1476 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1477 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1478 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1479 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1480 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1481 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1482 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1483 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1484 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1485 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1486 0x04,0x00 };
1487 static const BYTE signedWithCertAndCrlBareContent[] = {
1488 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1489 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1490 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1491 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1492 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1493 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1494 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1495 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1496 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1497 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1498 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1499 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1500 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1501 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1502 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1503 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1504 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1505 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1506 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1507 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1508 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1509 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1510 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1511 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1512 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1513 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1514 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1515 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1516 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1517 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1518 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1519 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1520 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1521 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1522 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1523 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1524 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1525 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1526 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1527 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1528 static BYTE v1CertWithValidPubKey[] = {
1529 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1530 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1531 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1532 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1533 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1534 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1535 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1536 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1537 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1538 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1539 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1540 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1541 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1542 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1543 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1544 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1545 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1546 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1547 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1548 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1549 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1550 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1551 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1552 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1553 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1554 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1555 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1556 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1557 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1558 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1559 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1560 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1561 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1562 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1563 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1564 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1565 0x00 };
1566 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1567 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1568 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1569 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1570 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1571 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1572 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1573 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1574 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1575 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1576 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1577 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1578 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1579 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1580 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1581 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1582 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1583 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1584 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1585 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1586 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1587 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1588 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1589 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1590 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1591 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1592 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1593 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1595 static void test_signed_msg_encoding(void)
1597 HCRYPTMSG msg;
1598 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1599 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1600 CERT_INFO certInfo = { 0 };
1601 CERT_BLOB encodedCert = { sizeof(cert), cert };
1602 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1603 char oid_common_name[] = szOID_COMMON_NAME;
1604 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1605 encodedCommonName };
1606 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1607 BOOL ret;
1608 HCRYPTKEY key;
1609 DWORD size;
1611 certInfo.SerialNumber.cbData = sizeof(serialNum);
1612 certInfo.SerialNumber.pbData = serialNum;
1613 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1614 certInfo.Issuer.pbData = encodedCommonName;
1615 signer.pCertInfo = &certInfo;
1616 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1617 signInfo.cSigners = 1;
1618 signInfo.rgSigners = &signer;
1620 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1621 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1622 if (!ret && GetLastError() == NTE_EXISTS) {
1623 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1624 PROV_RSA_FULL, 0);
1626 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1628 if (!ret) {
1629 skip("No context for tests\n");
1630 return;
1633 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1634 0, 0, &key);
1635 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1637 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1638 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1639 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1641 check_param("detached signed empty bare content", msg,
1642 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1643 sizeof(signedEmptyBareContent));
1644 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1645 signedEmptyContent, sizeof(signedEmptyContent));
1646 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1647 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1648 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1649 signedHash, sizeof(signedHash));
1650 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1651 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1652 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1653 detachedSignedContent, sizeof(detachedSignedContent));
1654 SetLastError(0xdeadbeef);
1655 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1656 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1657 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1658 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1659 signedEncodedSigner, sizeof(signedEncodedSigner));
1661 CryptMsgClose(msg);
1663 certInfo.SerialNumber.cbData = 0;
1664 certInfo.Issuer.cbData = 0;
1665 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1666 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1667 U(signer.SignerId).KeyId.pbData = (BYTE *)serialNum;
1668 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1669 NULL, NULL);
1670 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1671 check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM,
1672 signedKeyIdEmptyContent, sizeof(signedKeyIdEmptyContent));
1673 CryptMsgClose(msg);
1675 certInfo.SerialNumber.cbData = sizeof(serialNum);
1676 certInfo.SerialNumber.pbData = serialNum;
1677 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1678 certInfo.Issuer.pbData = encodedCommonName;
1679 signer.SignerId.dwIdChoice = 0;
1680 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1681 NULL, NULL);
1682 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1684 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1685 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1686 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1687 signedEmptyContent, sizeof(signedEmptyContent));
1688 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1689 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1690 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1691 signedBareContent, sizeof(signedBareContent));
1692 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1693 signedContent, sizeof(signedContent));
1695 CryptMsgClose(msg);
1697 signer.cAuthAttr = 1;
1698 signer.rgAuthAttr = &attr;
1699 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1700 NULL, NULL);
1701 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1703 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1704 check_param("signed with auth attrs bare content", msg,
1705 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1706 sizeof(signedWithAuthAttrsBareContent));
1708 CryptMsgClose(msg);
1710 signer.cAuthAttr = 0;
1711 signInfo.rgCertEncoded = &encodedCert;
1712 signInfo.cCertEncoded = 1;
1713 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1714 NULL, NULL);
1715 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1717 check_param("signed with cert empty bare content", msg,
1718 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1719 sizeof(signedWithCertEmptyBareContent));
1720 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1721 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1722 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1723 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1725 CryptMsgClose(msg);
1727 signInfo.cCertEncoded = 0;
1728 signInfo.rgCrlEncoded = &encodedCrl;
1729 signInfo.cCrlEncoded = 1;
1730 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1731 NULL, NULL);
1732 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1734 check_param("signed with crl empty bare content", msg,
1735 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1736 sizeof(signedWithCrlEmptyBareContent));
1737 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1738 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1739 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1740 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1742 CryptMsgClose(msg);
1744 signInfo.cCertEncoded = 1;
1745 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1746 NULL, NULL);
1747 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1749 check_param("signed with cert and crl empty bare content", msg,
1750 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1751 sizeof(signedWithCertAndCrlEmptyBareContent));
1752 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1753 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1754 check_param("signed with cert and crl bare content", msg,
1755 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1756 sizeof(signedWithCertAndCrlBareContent));
1758 CryptMsgClose(msg);
1760 /* Test with a cert with a (bogus) public key */
1761 signInfo.cCrlEncoded = 0;
1762 encodedCert.cbData = sizeof(v1CertWithPubKey);
1763 encodedCert.pbData = v1CertWithPubKey;
1764 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1765 NULL, NULL);
1766 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1767 check_param("signedWithCertWithPubKeyBareContent", msg,
1768 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1769 sizeof(signedWithCertWithPubKeyBareContent));
1770 CryptMsgClose(msg);
1772 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1773 encodedCert.pbData = v1CertWithValidPubKey;
1774 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1775 NULL, NULL);
1776 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1777 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1778 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1779 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1780 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1781 check_param("signedWithCertWithValidPubKeyContent", msg,
1782 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1783 sizeof(signedWithCertWithValidPubKeyContent));
1784 CryptMsgClose(msg);
1786 CryptDestroyKey(key);
1787 CryptReleaseContext(signer.hCryptProv, 0);
1788 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1789 CRYPT_DELETEKEYSET);
1792 static void test_signed_msg_get_param(void)
1794 BOOL ret;
1795 HCRYPTMSG msg;
1796 DWORD size, value = 0;
1797 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1798 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1799 CERT_INFO certInfo = { 0 };
1801 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1802 NULL, NULL);
1803 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1805 /* Content and bare content are always gettable */
1806 size = 0;
1807 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1808 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1809 size = 0;
1810 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1811 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1812 /* For "signed" messages, so is the version. */
1813 size = 0;
1814 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1815 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1816 size = sizeof(value);
1817 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1818 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1819 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1820 /* But for this message, with no signers, the hash and signer aren't
1821 * available.
1823 size = 0;
1824 SetLastError(0xdeadbeef);
1825 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1826 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1827 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1828 SetLastError(0xdeadbeef);
1829 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1830 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1831 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1832 /* As usual, the type isn't available. */
1833 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1834 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1835 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1837 CryptMsgClose(msg);
1839 certInfo.SerialNumber.cbData = sizeof(serialNum);
1840 certInfo.SerialNumber.pbData = serialNum;
1841 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1842 certInfo.Issuer.pbData = encodedCommonName;
1843 signer.pCertInfo = &certInfo;
1844 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1845 signInfo.cSigners = 1;
1846 signInfo.rgSigners = &signer;
1848 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1849 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1850 if (!ret && GetLastError() == NTE_EXISTS) {
1851 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1852 PROV_RSA_FULL, 0);
1854 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1856 if (!ret) {
1857 skip("No context for tests\n");
1858 return;
1861 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1862 NULL, NULL);
1863 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1865 /* This message, with one signer, has the hash and signer for index 0
1866 * available, but not for other indexes.
1868 size = 0;
1869 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1870 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1871 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1872 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1873 size = 0;
1874 SetLastError(0xdeadbeef);
1875 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1876 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1877 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1878 SetLastError(0xdeadbeef);
1879 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1880 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1881 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1882 /* As usual, the type isn't available. */
1883 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1884 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1885 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1887 CryptMsgClose(msg);
1889 /* Opening the message using the CMS fields.. */
1890 certInfo.SerialNumber.cbData = 0;
1891 certInfo.Issuer.cbData = 0;
1892 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1893 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1894 sizeof(encodedCommonName);
1895 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData =
1896 (BYTE *)encodedCommonName;
1897 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1898 sizeof(serialNum);
1899 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
1900 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1901 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1902 if (!ret && GetLastError() == NTE_EXISTS)
1903 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1904 PROV_RSA_FULL, 0);
1905 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1906 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1907 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1908 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1909 /* still results in the version being 1 when the issuer and serial number
1910 * are used and no additional CMS fields are used.
1912 size = sizeof(value);
1913 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1914 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1915 ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value);
1916 /* Apparently the encoded signer can be retrieved.. */
1917 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1918 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1919 /* but the signer info, CMS signer info, and cert ID can't be. */
1920 SetLastError(0xdeadbeef);
1921 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1922 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1923 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1924 SetLastError(0xdeadbeef);
1925 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1926 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1927 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1928 SetLastError(0xdeadbeef);
1929 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1930 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1931 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1932 CryptMsgClose(msg);
1934 /* Using the KeyId field of the SignerId results in the version becoming
1935 * the CMS version.
1937 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1938 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1939 U(signer.SignerId).KeyId.pbData = (BYTE *)serialNum;
1940 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1941 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1942 if (!ret && GetLastError() == NTE_EXISTS)
1943 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1944 PROV_RSA_FULL, 0);
1945 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1946 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1947 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1948 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1949 size = sizeof(value);
1950 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1951 ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value);
1952 /* Even for a CMS message, the signer can be retrieved.. */
1953 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1954 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1955 /* but the signer info, CMS signer info, and cert ID can't be. */
1956 SetLastError(0xdeadbeef);
1957 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1958 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1959 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1960 SetLastError(0xdeadbeef);
1961 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1962 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1963 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1964 SetLastError(0xdeadbeef);
1965 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1966 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1967 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1968 CryptMsgClose(msg);
1970 CryptReleaseContext(signer.hCryptProv, 0);
1971 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1972 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1975 static void test_signed_msg(void)
1977 test_signed_msg_open();
1978 test_signed_msg_update();
1979 test_signed_msg_encoding();
1980 test_signed_msg_get_param();
1983 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1984 static const struct update_accum a4 = { 1, &b4 };
1986 static const BYTE bogusOIDContent[] = {
1987 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1988 0x04,0x00 };
1989 static const BYTE bogusHashContent[] = {
1990 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1991 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1992 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1993 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1994 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1996 static void test_decode_msg_update(void)
1998 HCRYPTMSG msg;
1999 BOOL ret;
2000 CMSG_STREAM_INFO streamInfo = { 0 };
2001 DWORD i;
2002 struct update_accum accum = { 0, NULL };
2004 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2005 /* Update with a full message in a final update */
2006 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2007 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2008 /* Can't update after a final update */
2009 SetLastError(0xdeadbeef);
2010 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2011 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2012 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2013 CryptMsgClose(msg);
2015 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2016 /* Can't send a non-final update without streaming */
2017 SetLastError(0xdeadbeef);
2018 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2019 FALSE);
2020 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2021 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2022 /* A subsequent final update succeeds */
2023 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2024 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2025 CryptMsgClose(msg);
2027 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2028 /* Updating a message that has a NULL stream callback fails */
2029 SetLastError(0xdeadbeef);
2030 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2031 FALSE);
2032 todo_wine
2033 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2034 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2035 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2036 GetLastError());
2037 /* Changing the callback pointer after the fact yields the same error (so
2038 * the message must copy the stream info, not just store a pointer to it)
2040 streamInfo.pfnStreamOutput = nop_stream_output;
2041 SetLastError(0xdeadbeef);
2042 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2043 FALSE);
2044 todo_wine
2045 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2046 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2047 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2048 GetLastError());
2049 CryptMsgClose(msg);
2051 /* Empty non-final updates are allowed when streaming.. */
2052 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2053 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2054 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2055 /* but final updates aren't when not enough data has been received. */
2056 SetLastError(0xdeadbeef);
2057 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2058 todo_wine
2059 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2060 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2061 CryptMsgClose(msg);
2063 /* Updating the message byte by byte is legal */
2064 streamInfo.pfnStreamOutput = accumulating_stream_output;
2065 streamInfo.pvArg = &accum;
2066 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2067 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2068 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2069 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2070 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2071 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2072 CryptMsgClose(msg);
2073 todo_wine
2074 check_updates("byte-by-byte empty content", &a4, &accum);
2075 free_updates(&accum);
2077 /* Decoding bogus content fails in non-streaming mode.. */
2078 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2079 SetLastError(0xdeadbeef);
2080 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2081 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2082 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2083 CryptMsgClose(msg);
2084 /* and as the final update in streaming mode.. */
2085 streamInfo.pfnStreamOutput = nop_stream_output;
2086 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2087 SetLastError(0xdeadbeef);
2088 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2089 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2090 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2091 CryptMsgClose(msg);
2092 /* and even as a non-final update in streaming mode. */
2093 streamInfo.pfnStreamOutput = nop_stream_output;
2094 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2095 SetLastError(0xdeadbeef);
2096 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2097 todo_wine
2098 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2099 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2100 CryptMsgClose(msg);
2102 /* An empty message can be opened with undetermined type.. */
2103 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2104 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2105 TRUE);
2106 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2107 CryptMsgClose(msg);
2108 /* but decoding it as an explicitly typed message fails. */
2109 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2110 NULL);
2111 SetLastError(0xdeadbeef);
2112 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2113 TRUE);
2114 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2115 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2116 CryptMsgClose(msg);
2117 /* On the other hand, decoding the bare content of an empty message fails
2118 * with unspecified type..
2120 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2121 SetLastError(0xdeadbeef);
2122 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2123 sizeof(dataEmptyBareContent), TRUE);
2124 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2125 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2126 CryptMsgClose(msg);
2127 /* but succeeds with explicit type. */
2128 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2129 NULL);
2130 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2131 sizeof(dataEmptyBareContent), TRUE);
2132 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2133 CryptMsgClose(msg);
2135 /* Decoding valid content with an unsupported OID fails */
2136 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2137 SetLastError(0xdeadbeef);
2138 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2139 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2140 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2141 CryptMsgClose(msg);
2143 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2144 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2145 SetLastError(0xdeadbeef);
2146 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2147 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2148 CryptMsgClose(msg);
2149 /* while with specified type it fails. */
2150 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2151 NULL);
2152 SetLastError(0xdeadbeef);
2153 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2154 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2155 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2156 CryptMsgClose(msg);
2157 /* On the other hand, decoding the bare content of an empty hash message
2158 * fails with unspecified type..
2160 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2161 SetLastError(0xdeadbeef);
2162 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2163 sizeof(hashEmptyBareContent), TRUE);
2164 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2165 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2166 CryptMsgClose(msg);
2167 /* but succeeds with explicit type. */
2168 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2169 NULL);
2170 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2171 sizeof(hashEmptyBareContent), TRUE);
2172 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2173 CryptMsgClose(msg);
2175 /* And again, opening a (non-empty) hash message with unspecified type
2176 * succeeds..
2178 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2179 SetLastError(0xdeadbeef);
2180 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2181 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2182 CryptMsgClose(msg);
2183 /* while with specified type it fails.. */
2184 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2185 NULL);
2186 SetLastError(0xdeadbeef);
2187 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2188 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2189 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2190 CryptMsgClose(msg);
2191 /* and decoding the bare content of a non-empty hash message fails with
2192 * unspecified type..
2194 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2195 SetLastError(0xdeadbeef);
2196 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2197 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2198 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2199 CryptMsgClose(msg);
2200 /* but succeeds with explicit type. */
2201 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2202 NULL);
2203 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2204 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2205 CryptMsgClose(msg);
2207 /* Opening a (non-empty) hash message with unspecified type and a bogus
2208 * hash value succeeds..
2210 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2211 SetLastError(0xdeadbeef);
2212 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2213 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2214 CryptMsgClose(msg);
2216 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2217 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2218 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2219 CryptMsgClose(msg);
2220 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2221 SetLastError(0xdeadbeef);
2222 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2223 sizeof(signedWithCertAndCrlBareContent), TRUE);
2224 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2225 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2226 CryptMsgClose(msg);
2227 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2228 NULL);
2229 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2230 sizeof(signedWithCertAndCrlBareContent), TRUE);
2231 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2232 CryptMsgClose(msg);
2234 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2235 NULL, NULL);
2236 /* The first update succeeds.. */
2237 ret = CryptMsgUpdate(msg, detachedSignedContent,
2238 sizeof(detachedSignedContent), TRUE);
2239 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2240 /* as does a second (probably to update the detached portion).. */
2241 ret = CryptMsgUpdate(msg, detachedSignedContent,
2242 sizeof(detachedSignedContent), TRUE);
2243 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2244 /* while a third fails. */
2245 ret = CryptMsgUpdate(msg, detachedSignedContent,
2246 sizeof(detachedSignedContent), TRUE);
2247 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2248 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2249 CryptMsgClose(msg);
2251 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2252 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2253 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2254 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2255 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2256 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2257 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2258 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2259 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2261 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2262 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2263 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2264 CryptMsgClose(msg);
2267 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2268 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2270 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2271 const CMSG_SIGNER_INFO *expected)
2273 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2274 expected->dwVersion, got->dwVersion);
2275 ok(got->Issuer.cbData == expected->Issuer.cbData,
2276 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2277 got->Issuer.cbData);
2278 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2279 "Unexpected issuer\n");
2280 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2281 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2282 got->SerialNumber.cbData);
2283 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2284 got->SerialNumber.cbData), "Unexpected serial number\n");
2285 /* FIXME: check more things */
2288 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2289 const CMSG_CMS_SIGNER_INFO *expected)
2291 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2292 expected->dwVersion, got->dwVersion);
2293 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2294 "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2295 got->SignerId.dwIdChoice);
2296 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2298 if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2300 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2301 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2302 "Expected issuer size %d, got %d\n",
2303 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2304 U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2305 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2306 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2307 U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2308 "Unexpected issuer\n");
2309 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2310 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2311 "Expected serial number size %d, got %d\n",
2312 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2313 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2314 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2315 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2316 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2317 "Unexpected serial number\n");
2319 else
2321 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2322 "expected key id size %d, got %d\n",
2323 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2324 ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2325 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2326 "unexpected key id\n");
2329 /* FIXME: check more things */
2332 static const BYTE signedWithCertAndCrlComputedHash[] = {
2333 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2334 0x2f };
2335 static BYTE keyIdIssuer[] = {
2336 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2337 0x0a,0x07,0x01,0x04,0x01,0x01 };
2339 static void test_decode_msg_get_param(void)
2341 HCRYPTMSG msg;
2342 BOOL ret;
2343 DWORD size = 0, value;
2344 LPBYTE buf;
2346 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2347 SetLastError(0xdeadbeef);
2348 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2349 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2350 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2351 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2352 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2353 sizeof(msgData));
2354 CryptMsgClose(msg);
2356 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2357 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2358 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2359 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2360 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2361 emptyHashParam, sizeof(emptyHashParam));
2362 CryptMsgClose(msg);
2363 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2364 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2365 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2366 sizeof(msgData));
2367 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2368 sizeof(hashParam));
2369 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2370 hashParam, sizeof(hashParam));
2371 /* Curiously, getting the hash of index 1 succeeds, even though there's
2372 * only one hash.
2374 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2375 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2376 buf = CryptMemAlloc(size);
2377 if (buf)
2379 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2380 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2381 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2382 CryptMemFree(buf);
2384 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2385 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2386 value = CMSG_HASHED_DATA_V0;
2387 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2388 sizeof(value));
2389 CryptMsgClose(msg);
2391 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2392 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2393 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2394 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2395 sizeof(msgData));
2396 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2397 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2398 size = sizeof(value);
2399 value = 2112;
2400 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2401 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2402 ok(value == 1, "Expected 1 signer, got %d\n", value);
2403 size = 0;
2404 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2405 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2406 if (ret)
2407 buf = CryptMemAlloc(size);
2408 else
2409 buf = NULL;
2410 if (buf)
2412 CMSG_SIGNER_INFO signer = { 0 };
2414 signer.dwVersion = 1;
2415 signer.Issuer.cbData = sizeof(encodedCommonName);
2416 signer.Issuer.pbData = encodedCommonName;
2417 signer.SerialNumber.cbData = sizeof(serialNum);
2418 signer.SerialNumber.pbData = serialNum;
2419 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2420 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2421 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2422 CryptMemFree(buf);
2424 /* Getting the CMS signer info of a PKCS7 message is possible. */
2425 size = 0;
2426 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2427 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2428 if (ret)
2429 buf = CryptMemAlloc(size);
2430 else
2431 buf = NULL;
2432 if (buf)
2434 CMSG_CMS_SIGNER_INFO signer = { 0 };
2436 signer.dwVersion = 1;
2437 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2438 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2439 sizeof(encodedCommonName);
2440 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2441 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2442 sizeof(serialNum);
2443 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2444 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2445 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2446 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2447 CryptMemFree(buf);
2449 /* index is ignored when getting signer count */
2450 size = sizeof(value);
2451 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2452 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2453 ok(value == 1, "Expected 1 signer, got %d\n", value);
2454 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2455 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2456 ok(value == 0, "Expected 0 certs, got %d\n", value);
2457 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2458 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2459 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2460 CryptMsgClose(msg);
2461 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2462 NULL);
2463 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2464 sizeof(signedWithCertAndCrlBareContent), TRUE);
2465 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2466 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2467 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2468 ok(value == 1, "Expected 1 cert, got %d\n", value);
2469 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2470 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2471 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2472 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2473 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2474 check_param("signed with cert and CRL computed hash", msg,
2475 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2476 sizeof(signedWithCertAndCrlComputedHash));
2477 CryptMsgClose(msg);
2479 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2480 ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
2481 sizeof(signedKeyIdEmptyContent), TRUE);
2482 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2483 size = sizeof(value);
2484 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2485 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2486 ok(value == 1, "Expected 1 signer, got %d\n", value);
2487 /* Getting the regular (non-CMS) signer info from a CMS message is also
2488 * possible..
2490 size = 0;
2491 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2492 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2493 if (ret)
2494 buf = CryptMemAlloc(size);
2495 else
2496 buf = NULL;
2497 if (buf)
2499 CMSG_SIGNER_INFO signer;
2500 BYTE zero = 0;
2502 /* and here's the little oddity: for a CMS message using the key id
2503 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
2504 * a signer with a zero (not empty) serial number, and whose issuer is
2505 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
2506 * and value of the key id.
2508 signer.dwVersion = CMSG_SIGNED_DATA_V3;
2509 signer.Issuer.cbData = sizeof(keyIdIssuer);
2510 signer.Issuer.pbData = keyIdIssuer;
2511 signer.SerialNumber.cbData = 1;
2512 signer.SerialNumber.pbData = &zero;
2513 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2514 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2515 CryptMemFree(buf);
2517 size = 0;
2518 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2519 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2520 if (ret)
2521 buf = CryptMemAlloc(size);
2522 else
2523 buf = NULL;
2524 if (buf)
2526 CMSG_CMS_SIGNER_INFO signer = { 0 };
2528 signer.dwVersion = CMSG_SIGNED_DATA_V3;
2529 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2530 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
2531 U(signer.SignerId).KeyId.pbData = (BYTE *)serialNum;
2532 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2533 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2534 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2535 CryptMemFree(buf);
2537 CryptMsgClose(msg);
2540 static void test_decode_msg(void)
2542 test_decode_msg_update();
2543 test_decode_msg_get_param();
2546 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2547 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2548 static BYTE encodedPubKey[] = {
2549 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2550 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2551 0x0d,0x0e,0x0f };
2552 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2553 static BYTE mod_encoded[] = {
2554 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2555 0x01,0x00,0x01 };
2557 static void test_msg_control(void)
2559 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2560 BOOL ret;
2561 HCRYPTMSG msg;
2562 DWORD i;
2563 CERT_INFO certInfo = { 0 };
2564 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2565 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2566 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2568 /* Crashes
2569 ret = CryptMsgControl(NULL, 0, 0, NULL);
2572 /* Data encode messages don't allow any sort of control.. */
2573 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2574 NULL);
2575 /* either with no prior update.. */
2576 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2578 SetLastError(0xdeadbeef);
2579 ret = CryptMsgControl(msg, 0, i, NULL);
2580 ok(!ret && GetLastError() == E_INVALIDARG,
2581 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2583 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2584 /* or after an update. */
2585 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2587 SetLastError(0xdeadbeef);
2588 ret = CryptMsgControl(msg, 0, i, NULL);
2589 ok(!ret && GetLastError() == E_INVALIDARG,
2590 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2592 CryptMsgClose(msg);
2594 /* Hash encode messages don't allow any sort of control.. */
2595 hashInfo.cbSize = sizeof(hashInfo);
2596 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2597 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2598 NULL, NULL);
2599 /* either with no prior update.. */
2600 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2602 SetLastError(0xdeadbeef);
2603 ret = CryptMsgControl(msg, 0, i, NULL);
2604 ok(!ret && GetLastError() == E_INVALIDARG,
2605 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2607 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2608 /* or after an update. */
2609 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2611 SetLastError(0xdeadbeef);
2612 ret = CryptMsgControl(msg, 0, i, NULL);
2613 ok(!ret && GetLastError() == E_INVALIDARG,
2614 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2616 CryptMsgClose(msg);
2618 /* Signed encode messages likewise don't allow any sort of control.. */
2619 signInfo.cbSize = sizeof(signInfo);
2620 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2621 NULL, NULL);
2622 /* either before an update.. */
2623 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2625 SetLastError(0xdeadbeef);
2626 ret = CryptMsgControl(msg, 0, i, NULL);
2627 ok(!ret && GetLastError() == E_INVALIDARG,
2628 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2630 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2631 /* or after an update. */
2632 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2634 SetLastError(0xdeadbeef);
2635 ret = CryptMsgControl(msg, 0, i, NULL);
2636 ok(!ret && GetLastError() == E_INVALIDARG,
2637 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2639 CryptMsgClose(msg);
2641 /* Decode messages behave a bit differently. */
2642 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2643 /* Bad control type */
2644 SetLastError(0xdeadbeef);
2645 ret = CryptMsgControl(msg, 0, 0, NULL);
2646 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2647 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2648 SetLastError(0xdeadbeef);
2649 ret = CryptMsgControl(msg, 1, 0, NULL);
2650 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2651 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2652 /* Can't verify the hash of an indeterminate-type message */
2653 SetLastError(0xdeadbeef);
2654 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2655 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2656 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2657 /* Crashes
2658 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2660 /* Can't decrypt an indeterminate-type message */
2661 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2662 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2663 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2664 CryptMsgClose(msg);
2666 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2667 NULL);
2668 /* Can't verify the hash of an empty message */
2669 SetLastError(0xdeadbeef);
2670 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2671 todo_wine
2672 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2673 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2674 /* Crashes
2675 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2677 /* Can't verify the signature of a hash message */
2678 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2679 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2680 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2681 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2682 TRUE);
2683 /* Oddly enough, this fails */
2684 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2685 ok(!ret, "Expected failure\n");
2686 CryptMsgClose(msg);
2687 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2688 NULL);
2689 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2690 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2691 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2692 /* Can't decrypt an indeterminate-type message */
2693 SetLastError(0xdeadbeef);
2694 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2695 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2696 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2697 CryptMsgClose(msg);
2699 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2700 NULL, NULL);
2701 /* Can't verify the hash of a detached message before it's been updated. */
2702 SetLastError(0xdeadbeef);
2703 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2704 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2705 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2706 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
2707 TRUE);
2708 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2709 /* Still can't verify the hash of a detached message with the content
2710 * of the detached hash given..
2712 SetLastError(0xdeadbeef);
2713 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2714 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
2715 "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
2716 /* and giving the content of the message after attempting to verify the
2717 * hash fails.
2719 SetLastError(0xdeadbeef);
2720 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2721 todo_wine
2722 ok(!ret &&
2723 (GetLastError() == NTE_BAD_HASH_STATE ||
2724 GetLastError() == NTE_BAD_ALGID || /* Win9x */
2725 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
2726 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
2727 "got %08x\n", GetLastError());
2728 CryptMsgClose(msg);
2730 /* Finally, verifying the hash of a detached message in the correct order:
2731 * 1. Update with the detached hash message
2732 * 2. Update with the content of the message
2733 * 3. Verifying the hash of the message
2734 * succeeds.
2736 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2737 NULL, NULL);
2738 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
2739 TRUE);
2740 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2741 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2742 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2743 SetLastError(0xdeadbeef);
2744 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2745 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2746 CryptMsgClose(msg);
2748 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2749 NULL);
2750 /* Can't verify the hash of a signed message */
2751 SetLastError(0xdeadbeef);
2752 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2753 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2754 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2755 /* Can't decrypt a signed message */
2756 SetLastError(0xdeadbeef);
2757 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2758 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2759 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2760 /* Crash
2761 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2762 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2764 CryptMsgUpdate(msg, signedWithCertBareContent,
2765 sizeof(signedWithCertBareContent), TRUE);
2766 /* With an empty cert info, the signer can't be found in the message (and
2767 * the signature can't be verified.
2769 SetLastError(0xdeadbeef);
2770 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2771 ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2772 "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2773 /* The cert info is expected to have an issuer, serial number, and public
2774 * key info set.
2776 certInfo.SerialNumber.cbData = sizeof(serialNum);
2777 certInfo.SerialNumber.pbData = serialNum;
2778 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2779 certInfo.Issuer.pbData = encodedCommonName;
2780 SetLastError(0xdeadbeef);
2781 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2782 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2783 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2784 CryptMsgClose(msg);
2785 /* This cert has a public key, but it's not in a usable form */
2786 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2787 NULL);
2788 CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2789 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2790 /* Again, cert info needs to have a public key set */
2791 SetLastError(0xdeadbeef);
2792 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2793 ok(!ret &&
2794 (GetLastError() == CRYPT_E_ASN1_EOD ||
2795 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2796 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2797 /* The public key is supposed to be in encoded form.. */
2798 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2799 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2800 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2801 SetLastError(0xdeadbeef);
2802 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2803 ok(!ret &&
2804 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2805 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2806 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2807 /* but not as a X509_PUBLIC_KEY_INFO.. */
2808 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2809 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2810 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2811 SetLastError(0xdeadbeef);
2812 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2813 ok(!ret &&
2814 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2815 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2816 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2817 /* This decodes successfully, but it doesn't match any key in the message */
2818 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2819 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2820 SetLastError(0xdeadbeef);
2821 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2822 /* In Wine's rsaenh, this fails to decode because the key length is too
2823 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
2824 * now.
2826 todo_wine
2827 ok(!ret &&
2828 (GetLastError() == NTE_BAD_SIGNATURE ||
2829 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2830 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2831 CryptMsgClose(msg);
2832 /* A message with no data doesn't have a valid signature */
2833 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2834 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2835 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2836 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2837 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2838 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2839 SetLastError(0xdeadbeef);
2840 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2841 ok(!ret &&
2842 (GetLastError() == NTE_BAD_SIGNATURE ||
2843 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2844 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2845 CryptMsgClose(msg);
2846 /* Finally, this succeeds */
2847 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2848 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2849 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2850 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2851 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2852 CryptMsgClose(msg);
2854 /* Test verifying signature of a detached signed message */
2855 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2856 NULL, NULL);
2857 ret = CryptMsgUpdate(msg, detachedSignedContent,
2858 sizeof(detachedSignedContent), TRUE);
2859 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2860 /* Can't verify the sig without having updated the data */
2861 SetLastError(0xdeadbeef);
2862 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2863 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2864 "expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2865 /* Now that the signature's been checked, can't do the final update */
2866 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2867 todo_wine
2868 ok(!ret &&
2869 (GetLastError() == NTE_BAD_HASH_STATE ||
2870 GetLastError() == NTE_BAD_ALGID || /* Win9x */
2871 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
2872 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
2873 "got %08x\n", GetLastError());
2874 CryptMsgClose(msg);
2875 /* Updating with the detached portion of the message and the data of the
2876 * the message allows the sig to be verified.
2878 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2879 NULL, NULL);
2880 ret = CryptMsgUpdate(msg, detachedSignedContent,
2881 sizeof(detachedSignedContent), TRUE);
2882 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2883 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2884 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2885 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2886 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2887 CryptMsgClose(msg);
2890 /* win9x has much less parameter checks and will crash on many tests
2891 * this code is from test_signed_msg_update()
2893 static BOOL detect_nt(void)
2895 BOOL ret;
2896 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
2897 CERT_INFO certInfo = { 0 };
2899 if (!pCryptAcquireContextW)
2900 return FALSE;
2902 certInfo.SerialNumber.cbData = sizeof(serialNum);
2903 certInfo.SerialNumber.pbData = serialNum;
2904 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2905 certInfo.Issuer.pbData = encodedCommonName;
2906 signer.pCertInfo = &certInfo;
2907 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2909 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2910 PROV_RSA_FULL, CRYPT_NEWKEYSET);
2911 if (!ret && GetLastError() == NTE_EXISTS) {
2912 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2913 PROV_RSA_FULL, 0);
2916 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
2918 /* cleanup */
2919 CryptReleaseContext(signer.hCryptProv, 0);
2920 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
2921 CRYPT_DELETEKEYSET);
2923 return TRUE;
2926 static void test_msg_get_and_verify_signer(void)
2928 BOOL ret;
2929 HCRYPTMSG msg;
2930 PCCERT_CONTEXT signer;
2931 DWORD signerIndex;
2932 HCERTSTORE store;
2934 /* Crash */
2935 if (0)
2937 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
2938 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
2941 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2942 /* An empty message has no signer */
2943 SetLastError(0xdeadbeef);
2944 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2945 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2946 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2947 /* The signer is cleared on error */
2948 signer = (PCCERT_CONTEXT)0xdeadbeef;
2949 SetLastError(0xdeadbeef);
2950 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2951 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2952 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2953 ok(!signer, "expected signer to be NULL\n");
2954 /* The signer index is also cleared on error */
2955 signerIndex = 0xdeadbeef;
2956 SetLastError(0xdeadbeef);
2957 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2958 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2959 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2960 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
2961 /* An unsigned message (msgData isn't a signed message at all)
2962 * likewise has no signer.
2964 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2965 SetLastError(0xdeadbeef);
2966 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2967 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2968 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2969 CryptMsgClose(msg);
2971 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2972 /* A "signed" message created with no signer cert likewise has no signer */
2973 CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
2974 SetLastError(0xdeadbeef);
2975 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2976 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2977 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2978 CryptMsgClose(msg);
2980 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2981 /* A signed message succeeds, .. */
2982 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2983 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2984 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2985 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2986 /* the signer index can be retrieved, .. */
2987 signerIndex = 0xdeadbeef;
2988 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2989 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2990 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
2991 /* as can the signer cert. */
2992 signer = (PCCERT_CONTEXT)0xdeadbeef;
2993 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2994 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2995 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
2996 "expected a valid signer\n");
2997 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
2998 CertFreeCertificateContext(signer);
2999 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3001 signerIndex = 0xdeadbeef;
3002 SetLastError(0xdeadbeef);
3003 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3004 NULL, &signerIndex);
3005 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3006 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3007 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3008 * message signer not to be found.
3010 SetLastError(0xdeadbeef);
3011 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3012 NULL, NULL);
3013 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3014 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3015 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3016 * the message signer not to be found.
3018 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3019 CERT_STORE_CREATE_NEW_FLAG, NULL);
3020 SetLastError(0xdeadbeef);
3021 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3022 NULL, NULL);
3023 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3024 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3025 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3026 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3027 CERT_STORE_ADD_ALWAYS, NULL);
3028 ok(ret, "CertAddEncodedCertificateToStore failed: 0x%08x\n",
3029 GetLastError());
3030 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3031 * the signer succeeds.
3033 SetLastError(0xdeadbeef);
3034 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3035 NULL, NULL);
3036 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3037 CertCloseStore(store, 0);
3038 CryptMsgClose(msg);
3041 START_TEST(msg)
3043 init_function_pointers();
3044 have_nt = detect_nt();
3046 /* Basic parameter checking tests */
3047 test_msg_open_to_encode();
3048 test_msg_open_to_decode();
3049 test_msg_get_param();
3050 test_msg_close();
3051 test_msg_control();
3053 /* Message-type specific tests */
3054 test_data_msg();
3055 test_hash_msg();
3056 test_signed_msg();
3057 test_decode_msg();
3059 test_msg_get_and_verify_signer();