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