source: trunk/src/crypt32/tests/msg.c@ 21311

Last change on this file since 21311 was 21311, checked in by vladest, 16 years ago

Added CRYPT32 and MSCMS APIs support

File size: 140.6 KB
Line 
1/*
2 * Unit test suite for crypt32.dll's CryptMsg functions
3 *
4 * Copyright 2007 Juan Lang
5 *
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.
10 *
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.
15 *
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
19 */
20
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>
29
30#include "wine/test.h"
31
32static BOOL have_nt;
33static char oid_rsa_md5[] = szOID_RSA_MD5;
34
35static BOOL (WINAPI * pCryptAcquireContextA)
36 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
37static BOOL (WINAPI * pCryptAcquireContextW)
38 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
39
40static void init_function_pointers(void)
41{
42 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
43
44#define GET_PROC(dll, func) \
45 p ## func = (void *)GetProcAddress(dll, #func); \
46 if(!p ## func) \
47 trace("GetProcAddress(%s) failed\n", #func);
48
49 GET_PROC(hAdvapi32, CryptAcquireContextA)
50 GET_PROC(hAdvapi32, CryptAcquireContextW)
51
52#undef GET_PROC
53}
54
55static void test_msg_open_to_encode(void)
56{
57 HCRYPTMSG msg;
58
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);
66 */
67
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());
77
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());
98}
99
100static void test_msg_open_to_decode(void)
101{
102 HCRYPTMSG msg;
103 CMSG_STREAM_INFO streamInfo = { 0 };
104
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());
109
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());
119
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);
153
154 /* And even though the stream info parameter "must be set to NULL" for
155 * CMSG_HASHED, it's still accepted.
156 */
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);
161}
162
163static void test_msg_get_param(void)
164{
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 };
170
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);
175 */
176
177 /* Decoded messages */
178 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
179 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
180 /* For decoded messages, the type is always available */
181 size = 0;
182 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
183 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
184 size = sizeof(value);
185 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
186 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
187 /* For this (empty) message, the type isn't set */
188 ok(value == 0, "Expected type 0, got %d\n", value);
189 CryptMsgClose(msg);
190
191 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
192 NULL);
193 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
194 /* For explicitly typed messages, the type is known. */
195 size = sizeof(value);
196 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
197 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
198 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
199 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
200 {
201 size = 0;
202 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
203 ok(!ret, "Parameter %d: expected failure\n", i);
204 }
205 CryptMsgClose(msg);
206
207 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
208 NULL);
209 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
210 size = sizeof(value);
211 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
212 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
213 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
214 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
215 {
216 size = 0;
217 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
218 ok(!ret, "Parameter %d: expected failure\n", i);
219 }
220 CryptMsgClose(msg);
221
222 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
223 NULL);
224 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
225 size = sizeof(value);
226 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
227 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
228 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
229 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
230 {
231 size = 0;
232 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
233 ok(!ret, "Parameter %d: expected failure\n", i);
234 }
235 CryptMsgClose(msg);
236
237 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
238 NULL);
239 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
240 size = sizeof(value);
241 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
242 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
243 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
244 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
245 {
246 size = 0;
247 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
248 ok(!ret, "Parameter %d: expected failure\n", i);
249 }
250 CryptMsgClose(msg);
251
252 /* Explicitly typed messages get their types set, even if they're invalid */
253 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
254 NULL);
255 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
256 size = sizeof(value);
257 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
258 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
259 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
260 CryptMsgClose(msg);
261
262 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
263 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
264 size = sizeof(value);
265 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
266 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
267 ok(value == 1000, "Expected 1000, got %d\n", value);
268 CryptMsgClose(msg);
269}
270
271static void test_msg_close(void)
272{
273 BOOL ret;
274 HCRYPTMSG msg;
275
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());
287}
288
289static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
290 const BYTE *expected, DWORD expectedSize)
291{
292 DWORD size;
293 LPBYTE buf;
294 BOOL ret;
295
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);
307}
308
309static void test_data_msg_open(void)
310{
311 HCRYPTMSG msg;
312 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
313 CMSG_STREAM_INFO streamInfo = { 0 };
314 char oid[] = "1.2.3";
315
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);
326
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);
332
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.
345 */
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);
350}
351
352static const BYTE msgData[] = { 1, 2, 3, 4 };
353
354static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
355 BOOL final)
356{
357 return TRUE;
358}
359
360static void test_data_msg_update(void)
361{
362 HCRYPTMSG msg;
363 BOOL ret;
364 CMSG_STREAM_INFO streamInfo = { 0 };
365
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);
382
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.
391 */
392
393 /* Curiously, a valid update will now fail as well, presumably because of
394 * the last (invalid, but final) update.
395 */
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);
400
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);
415
416 /* Calling update after opening with an empty stream info (with a bogus
417 * output function) yields an error:
418 */
419 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
420 &streamInfo);
421 SetLastError(0xdeadbeef);
422 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
423 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
424 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
425 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
426 GetLastError());
427 CryptMsgClose(msg);
428 /* Calling update with a valid output function succeeds, even if the data
429 * exceeds the size specified in the stream info.
430 */
431 streamInfo.pfnStreamOutput = nop_stream_output;
432 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
433 &streamInfo);
434 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
435 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
436 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
437 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
438 CryptMsgClose(msg);
439}
440
441static void test_data_msg_get_param(void)
442{
443 HCRYPTMSG msg;
444 DWORD size;
445 BOOL ret;
446 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
447
448 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
449 NULL);
450
451 /* Content and bare content are always gettable when not streaming */
452 size = 0;
453 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
454 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
455 size = 0;
456 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
457 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
458 /* But for this type of message, the signer and hash aren't applicable,
459 * and the type isn't available.
460 */
461 size = 0;
462 SetLastError(0xdeadbeef);
463 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
464 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
465 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
466 SetLastError(0xdeadbeef);
467 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
468 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
469 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
470 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
471 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
472 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
473 CryptMsgClose(msg);
474
475 /* Can't get content or bare content when streaming */
476 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
477 NULL, &streamInfo);
478 SetLastError(0xdeadbeef);
479 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
480 ok(!ret && GetLastError() == E_INVALIDARG,
481 "Expected E_INVALIDARG, got %x\n", GetLastError());
482 SetLastError(0xdeadbeef);
483 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
484 ok(!ret && GetLastError() == E_INVALIDARG,
485 "Expected E_INVALIDARG, got %x\n", GetLastError());
486 CryptMsgClose(msg);
487}
488
489static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
490static const BYTE dataEmptyContent[] = {
4910x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
4920x04,0x00 };
493static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
494static const BYTE dataContent[] = {
4950x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
4960x04,0x04,0x01,0x02,0x03,0x04 };
497
498struct update_accum
499{
500 DWORD cUpdates;
501 CRYPT_DATA_BLOB *updates;
502};
503
504static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
505 DWORD cb, BOOL final)
506{
507 struct update_accum *accum = (struct update_accum *)pvArg;
508 BOOL ret = FALSE;
509
510 if (accum->cUpdates)
511 accum->updates = CryptMemRealloc(accum->updates,
512 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
513 else
514 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
515 if (accum->updates)
516 {
517 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
518
519 blob->pbData = CryptMemAlloc(cb);
520 if (blob->pbData)
521 {
522 memcpy(blob->pbData, pb, cb);
523 blob->cbData = cb;
524 ret = TRUE;
525 }
526 accum->cUpdates++;
527 }
528 return ret;
529}
530
531/* The updates of a (bogus) definite-length encoded message */
532static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
533 0x07,0x01,0xa0,0x02,0x04,0x00 };
534static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
535static CRYPT_DATA_BLOB b1[] = {
536 { sizeof(u1), u1 },
537 { sizeof(u2), u2 },
538 { sizeof(u2), u2 },
539};
540static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
541/* The updates of a definite-length encoded message */
542static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
543 0x07,0x01,0xa0,0x06,0x04,0x04 };
544static CRYPT_DATA_BLOB b2[] = {
545 { sizeof(u3), u3 },
546 { sizeof(u2), u2 },
547};
548static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
549/* The updates of an indefinite-length encoded message */
550static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
551 0x07,0x01,0xa0,0x80,0x24,0x80 };
552static BYTE u5[] = { 0x04,0x04 };
553static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
554static CRYPT_DATA_BLOB b3[] = {
555 { sizeof(u4), u4 },
556 { sizeof(u5), u5 },
557 { sizeof(u2), u2 },
558 { sizeof(u5), u5 },
559 { sizeof(u2), u2 },
560 { sizeof(u6), u6 },
561};
562static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
563
564static void check_updates(LPCSTR header, const struct update_accum *expected,
565 const struct update_accum *got)
566{
567 DWORD i;
568
569 ok(expected->cUpdates == got->cUpdates,
570 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
571 got->cUpdates);
572 if (expected->cUpdates == got->cUpdates)
573 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
574 {
575 ok(expected->updates[i].cbData == got->updates[i].cbData,
576 "%s, update %d: expected %d bytes, got %d\n", header, i,
577 expected->updates[i].cbData, got->updates[i].cbData);
578 if (expected->updates[i].cbData && expected->updates[i].cbData ==
579 got->updates[i].cbData)
580 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
581 got->updates[i].cbData), "%s, update %d: unexpected value\n",
582 header, i);
583 }
584}
585
586/* Frees the updates stored in accum */
587static void free_updates(struct update_accum *accum)
588{
589 DWORD i;
590
591 for (i = 0; i < accum->cUpdates; i++)
592 CryptMemFree(accum->updates[i].pbData);
593 CryptMemFree(accum->updates);
594 accum->updates = NULL;
595 accum->cUpdates = 0;
596}
597
598static void test_data_msg_encoding(void)
599{
600 HCRYPTMSG msg;
601 BOOL ret;
602 static char oid[] = "1.2.3";
603 struct update_accum accum = { 0, NULL };
604 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
605
606 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
607 NULL);
608 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
609 dataEmptyBareContent, sizeof(dataEmptyBareContent));
610 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
611 sizeof(dataEmptyContent));
612 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
613 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
614 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
615 dataBareContent, sizeof(dataBareContent));
616 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
617 sizeof(dataContent));
618 CryptMsgClose(msg);
619 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
620 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
621 CMSG_DATA, NULL, NULL, NULL);
622 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
623 dataEmptyBareContent, sizeof(dataEmptyBareContent));
624 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
625 sizeof(dataEmptyContent));
626 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
627 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
628 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
629 dataBareContent, sizeof(dataBareContent));
630 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
631 sizeof(dataContent));
632 CryptMsgClose(msg);
633 /* The inner OID is apparently ignored */
634 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
635 NULL);
636 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
637 dataEmptyBareContent, sizeof(dataEmptyBareContent));
638 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
639 dataEmptyContent, sizeof(dataEmptyContent));
640 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
641 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
642 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
643 dataBareContent, sizeof(dataBareContent));
644 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
645 sizeof(dataContent));
646 CryptMsgClose(msg);
647 /* A streaming message is DER encoded if the length is not 0xffffffff, but
648 * curiously, updates aren't validated to make sure they don't exceed the
649 * stated length. (The resulting output will of course fail to decode.)
650 */
651 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
652 NULL, &streamInfo);
653 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
654 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
655 CryptMsgClose(msg);
656 check_updates("bogus data message with definite length", &a1, &accum);
657 free_updates(&accum);
658 /* A valid definite-length encoding: */
659 streamInfo.cbContent = sizeof(msgData);
660 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
661 NULL, &streamInfo);
662 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
663 CryptMsgClose(msg);
664 check_updates("data message with definite length", &a2, &accum);
665 free_updates(&accum);
666 /* An indefinite-length encoding: */
667 streamInfo.cbContent = 0xffffffff;
668 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
669 NULL, &streamInfo);
670 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
671 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
672 CryptMsgClose(msg);
673 check_updates("data message with indefinite length", &a3, &accum);
674 free_updates(&accum);
675}
676
677static void test_data_msg(void)
678{
679 test_data_msg_open();
680 test_data_msg_update();
681 test_data_msg_get_param();
682 test_data_msg_encoding();
683}
684
685static void test_hash_msg_open(void)
686{
687 HCRYPTMSG msg;
688 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
689 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
690
691 SetLastError(0xdeadbeef);
692 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
693 NULL, NULL);
694 ok(!msg && GetLastError() == E_INVALIDARG,
695 "Expected E_INVALIDARG, got %x\n", GetLastError());
696 hashInfo.cbSize = sizeof(hashInfo);
697 SetLastError(0xdeadbeef);
698 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
699 NULL, NULL);
700 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
701 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
702 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
703 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
704 NULL, NULL);
705 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
706 CryptMsgClose(msg);
707 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
708 CMSG_HASHED, &hashInfo, NULL, NULL);
709 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
710 CryptMsgClose(msg);
711 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
712 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
713 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
714 CryptMsgClose(msg);
715}
716
717static void test_hash_msg_update(void)
718{
719 HCRYPTMSG msg;
720 BOOL ret;
721 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
722 { oid_rsa_md5, { 0, NULL } }, NULL };
723 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
724
725 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
726 CMSG_HASHED, &hashInfo, NULL, NULL);
727 /* Detached hashed messages opened in non-streaming mode allow non-final
728 * updates..
729 */
730 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
731 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
732 /* including non-final updates with no data.. */
733 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
734 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
735 /* and final updates with no data. */
736 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
737 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
738 /* But no updates are allowed after the final update. */
739 SetLastError(0xdeadbeef);
740 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
741 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
742 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
743 SetLastError(0xdeadbeef);
744 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
745 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
746 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
747 CryptMsgClose(msg);
748 /* Non-detached messages, in contrast, don't allow non-final updates in
749 * non-streaming mode.
750 */
751 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
752 NULL, NULL);
753 SetLastError(0xdeadbeef);
754 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
755 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
756 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
757 /* Final updates (including empty ones) are allowed. */
758 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
759 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
760 CryptMsgClose(msg);
761 /* And, of course, streaming mode allows non-final updates */
762 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
763 NULL, &streamInfo);
764 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
765 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
766 CryptMsgClose(msg);
767 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
768 * to be a bug, it isn't actually used - see encoding tests.)
769 */
770 streamInfo.pfnStreamOutput = NULL;
771 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
772 NULL, &streamInfo);
773 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
774 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
775 CryptMsgClose(msg);
776}
777
778static const BYTE emptyHashParam[] = {
7790xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
7800x7e };
781
782static void test_hash_msg_get_param(void)
783{
784 HCRYPTMSG msg;
785 BOOL ret;
786 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
787 { oid_rsa_md5, { 0, NULL } }, NULL };
788 DWORD size, value;
789 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
790 BYTE buf[16];
791
792 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
793 NULL, NULL);
794 /* Content and bare content are always gettable for non-streamed messages */
795 size = 0;
796 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
797 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
798 size = 0;
799 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
800 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
801 /* For an encoded hash message, the hash data aren't available */
802 SetLastError(0xdeadbeef);
803 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
804 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
805 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
806 /* The hash is also available. */
807 size = 0;
808 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
809 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
810 ok(size == sizeof(buf), "Unexpected size %d\n", size);
811 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
812 if (size == sizeof(buf))
813 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
814 /* By getting the hash, further updates are not allowed */
815 SetLastError(0xdeadbeef);
816 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
817 ok(!ret &&
818 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
819 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
820 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */),
821 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
822
823 /* Even after a final update, the hash data aren't available */
824 SetLastError(0xdeadbeef);
825 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
826 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
827 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
828 /* The version is also available, and should be zero for this message. */
829 size = 0;
830 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
831 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
832 size = sizeof(value);
833 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
834 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
835 ok(value == 0, "Expected version 0, got %d\n", value);
836 /* As usual, the type isn't available. */
837 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
838 ok(!ret, "Expected failure\n");
839 CryptMsgClose(msg);
840
841 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
842 NULL, &streamInfo);
843 /* Streamed messages don't allow you to get the content or bare content. */
844 SetLastError(0xdeadbeef);
845 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
846 ok(!ret && GetLastError() == E_INVALIDARG,
847 "Expected E_INVALIDARG, got %x\n", GetLastError());
848 SetLastError(0xdeadbeef);
849 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
850 ok(!ret && GetLastError() == E_INVALIDARG,
851 "Expected E_INVALIDARG, got %x\n", GetLastError());
852 /* The hash is still available. */
853 size = 0;
854 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
855 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
856 ok(size == sizeof(buf), "Unexpected size %d\n", size);
857 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
858 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
859 if (size == sizeof(buf))
860 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
861 /* After updating the hash, further updates aren't allowed on streamed
862 * messages either.
863 */
864 SetLastError(0xdeadbeef);
865 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
866 ok(!ret &&
867 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
868 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
869 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */),
870 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
871
872 CryptMsgClose(msg);
873}
874
875static const BYTE hashEmptyBareContent[] = {
8760x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
8770x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
878static const BYTE hashEmptyContent[] = {
8790x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
8800x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
8810x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
882static const BYTE hashBareContent[] = {
8830x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
8840x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
8850x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
8860x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
887static const BYTE hashContent[] = {
8880x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
8890x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
8900x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
8910x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
8920x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
893
894static const BYTE detachedHashNonFinalBareContent[] = {
8950x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
8960x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
8970x07,0x01,0x04,0x00 };
898static const BYTE detachedHashNonFinalContent[] = {
8990x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
9000x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
9010x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
9020x07,0x01,0x04,0x00 };
903static const BYTE detachedHashBareContent[] = {
9040x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
9050x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
9060x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
9070x9d,0x2a,0x8f,0x26,0x2f };
908static const BYTE detachedHashContent[] = {
9090x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
9100x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
9110x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
9120x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
9130x9d,0x2a,0x8f,0x26,0x2f };
914
915static void test_hash_msg_encoding(void)
916{
917 HCRYPTMSG msg;
918 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
919 BOOL ret;
920 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
921 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
922
923 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
924 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
925 NULL, NULL);
926 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
927 hashEmptyBareContent, sizeof(hashEmptyBareContent));
928 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
929 hashEmptyContent, sizeof(hashEmptyContent));
930 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
931 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
932 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
933 hashBareContent, sizeof(hashBareContent));
934 check_param("hash content", msg, CMSG_CONTENT_PARAM,
935 hashContent, sizeof(hashContent));
936 CryptMsgClose(msg);
937 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
938 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
939 CMSG_HASHED, &hashInfo, NULL, NULL);
940 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
941 hashEmptyBareContent, sizeof(hashEmptyBareContent));
942 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
943 hashEmptyContent, sizeof(hashEmptyContent));
944 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
945 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
946 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
947 hashBareContent, sizeof(hashBareContent));
948 check_param("hash content", msg, CMSG_CONTENT_PARAM,
949 hashContent, sizeof(hashContent));
950 CryptMsgClose(msg);
951 /* Same test, but with CMSG_DETACHED_FLAG set */
952 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
953 CMSG_HASHED, &hashInfo, NULL, NULL);
954 check_param("detached hash empty bare content", msg,
955 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
956 sizeof(hashEmptyBareContent));
957 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
958 hashEmptyContent, sizeof(hashEmptyContent));
959 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
960 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
961 check_param("detached hash not final bare content", msg,
962 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
963 sizeof(detachedHashNonFinalBareContent));
964 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
965 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
966 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
967 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
968 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
969 detachedHashBareContent, sizeof(detachedHashBareContent));
970 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
971 detachedHashContent, sizeof(detachedHashContent));
972 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
973 detachedHashBareContent, sizeof(detachedHashBareContent));
974 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
975 detachedHashContent, sizeof(detachedHashContent));
976 CryptMsgClose(msg);
977 /* In what appears to be a bug, streamed updates to hash messages don't
978 * call the output function.
979 */
980 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
981 NULL, &streamInfo);
982 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
983 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
984 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
985 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
986 CryptMsgClose(msg);
987 check_updates("empty hash message", &empty_accum, &accum);
988 free_updates(&accum);
989
990 streamInfo.cbContent = sizeof(msgData);
991 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
992 NULL, &streamInfo);
993 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
994 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
995 CryptMsgClose(msg);
996 check_updates("hash message", &empty_accum, &accum);
997 free_updates(&accum);
998
999 streamInfo.cbContent = sizeof(msgData);
1000 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
1001 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
1002 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1003 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1004 CryptMsgClose(msg);
1005 check_updates("detached hash message", &empty_accum, &accum);
1006 free_updates(&accum);
1007}
1008
1009static void test_hash_msg(void)
1010{
1011 test_hash_msg_open();
1012 test_hash_msg_update();
1013 test_hash_msg_get_param();
1014 test_hash_msg_encoding();
1015}
1016
1017static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1018 'm','p',0 };
1019static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1020 'm','p',0 };
1021static BYTE serialNum[] = { 1 };
1022static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1023 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1024
1025static void test_signed_msg_open(void)
1026{
1027 HCRYPTMSG msg;
1028 BOOL ret;
1029 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1030 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1031 CERT_INFO certInfo = { 0 };
1032
1033 SetLastError(0xdeadbeef);
1034 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1035 NULL, NULL);
1036 ok(!msg && GetLastError() == E_INVALIDARG,
1037 "Expected E_INVALIDARG, got %x\n", GetLastError());
1038 signInfo.cbSize = sizeof(signInfo);
1039 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1040 NULL, NULL);
1041 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1042 CryptMsgClose(msg);
1043
1044 signInfo.cSigners = 1;
1045 signInfo.rgSigners = &signer;
1046 /* With signer.pCertInfo unset, attempting to open this message this
1047 * crashes.
1048 */
1049 signer.pCertInfo = &certInfo;
1050 /* The cert info must contain a serial number and an issuer. */
1051 SetLastError(0xdeadbeef);
1052 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1053 NULL, NULL);
1054 /* NT: E_INVALIDARG, 9x: unchanged */
1055 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef),
1056 "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError());
1057
1058 certInfo.SerialNumber.cbData = sizeof(serialNum);
1059 certInfo.SerialNumber.pbData = serialNum;
1060 SetLastError(0xdeadbeef);
1061 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1062 NULL, NULL);
1063 /* NT: E_INVALIDARG, 9x: unchanged */
1064 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef),
1065 "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError());
1066
1067 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1068 certInfo.Issuer.pbData = encodedCommonName;
1069 SetLastError(0xdeadbeef);
1070 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1071 NULL, NULL);
1072 ok(!msg && GetLastError() == E_INVALIDARG,
1073 "Expected E_INVALIDARG, got %x\n", GetLastError());
1074
1075 /* The signer's hCryptProv must be set to something. Whether it's usable
1076 * or not will be checked after the hash algorithm is checked (see next
1077 * test.)
1078 */
1079 signer.hCryptProv = 1;
1080 SetLastError(0xdeadbeef);
1081 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1082 NULL, NULL);
1083 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1084 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1085 /* The signer's hash algorithm must also be set. */
1086 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1087 SetLastError(0xdeadbeef);
1088 /* Crashes in advapi32 in wine, don't do it */
1089 if (0) {
1090 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1091 &signInfo, NULL, NULL);
1092 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1093 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1094 }
1095 /* The signer's hCryptProv must also be valid. */
1096 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1097 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1098 if (!ret && GetLastError() == NTE_EXISTS) {
1099 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1100 PROV_RSA_FULL, 0);
1101 }
1102 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1103
1104 if (ret) {
1105 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1106 NULL, NULL);
1107 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1108 CryptMsgClose(msg);
1109 }
1110
1111 /* pCertInfo must still be set, but can be empty if the SignerId's issuer
1112 * and serial number are set.
1113 */
1114 certInfo.Issuer.cbData = 0;
1115 certInfo.SerialNumber.cbData = 0;
1116 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1117 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1118 sizeof(encodedCommonName);
1119 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData =
1120 (BYTE *)encodedCommonName;
1121 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1122 sizeof(serialNum);
1123 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
1124 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1125 NULL, NULL);
1126 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1127 CryptMsgClose(msg);
1128
1129 CryptReleaseContext(signer.hCryptProv, 0);
1130 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1131 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1132}
1133
1134static const BYTE privKey[] = {
1135 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1136 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1137 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1138 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1139 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1140 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1141 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1142 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1143 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1144 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1145 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1146 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1147 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1148 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1149 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1150 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1151 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1152 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1153 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1154 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1155 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1156 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1157 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1158 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1159static BYTE pubKey[] = {
11600x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
11610xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
11620x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
11630xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
11640x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1165
1166static void test_signed_msg_update(void)
1167{
1168 HCRYPTMSG msg;
1169 BOOL ret;
1170 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1171 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1172 CERT_INFO certInfo = { 0 };
1173 HCRYPTKEY key;
1174
1175 certInfo.SerialNumber.cbData = sizeof(serialNum);
1176 certInfo.SerialNumber.pbData = serialNum;
1177 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1178 certInfo.Issuer.pbData = encodedCommonName;
1179 signer.pCertInfo = &certInfo;
1180 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1181 signInfo.cSigners = 1;
1182 signInfo.rgSigners = &signer;
1183
1184 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1185 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1186 if (!ret && GetLastError() == NTE_EXISTS) {
1187 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1188 PROV_RSA_FULL, 0);
1189 }
1190 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1191
1192 if (!ret) {
1193 skip("No context for tests\n");
1194 return;
1195 }
1196
1197 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1198 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1199 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1200 /* Detached CMSG_SIGNED allows non-final updates. */
1201 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1202 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1203 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1204 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1205 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1206 /* The final update requires a private key in the hCryptProv, in order to
1207 * generate the signature.
1208 */
1209 SetLastError(0xdeadbeef);
1210 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1211 ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1212 GetLastError() == NTE_NO_KEY),
1213 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1214 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1215 0, 0, &key);
1216 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1217 /* The final update should be able to succeed now that a key exists, but
1218 * the previous (invalid) final update prevents it.
1219 */
1220 SetLastError(0xdeadbeef);
1221 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1222 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1223 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1224 CryptMsgClose(msg);
1225
1226 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1227 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1228 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1229 /* Detached CMSG_SIGNED allows non-final updates. */
1230 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1231 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1232 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1233 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1234 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1235 /* Now that the private key exists, the final update can succeed (even
1236 * with no data.)
1237 */
1238 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1239 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1240 /* But no updates are allowed after the final update. */
1241 SetLastError(0xdeadbeef);
1242 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1243 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1244 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1245 SetLastError(0xdeadbeef);
1246 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1247 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1248 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1249 CryptMsgClose(msg);
1250
1251 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1252 NULL, NULL);
1253 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1254 /* Non-detached messages don't allow non-final updates.. */
1255 SetLastError(0xdeadbeef);
1256 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1257 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1258 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1259 /* but they do allow final ones. */
1260 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1261 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1262 CryptMsgClose(msg);
1263 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1264 NULL, NULL);
1265 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1266 /* They also allow final updates with no data. */
1267 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1268 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1269 CryptMsgClose(msg);
1270
1271 CryptDestroyKey(key);
1272 CryptReleaseContext(signer.hCryptProv, 0);
1273 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1274 CRYPT_DELETEKEYSET);
1275}
1276
1277static const BYTE signedEmptyBareContent[] = {
12780x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
12790xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
12800x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
12810x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
12820x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
12830x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1284static const BYTE signedEmptyContent[] = {
12850x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
12860x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
12870xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
12880x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
12890x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
12900x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
12910x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1292static const BYTE detachedSignedBareContent[] = {
12930x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
12940x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
12950xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
12960x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
12970x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
12980x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
12990x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
13000x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
13010xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
13020xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
13030xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1304static const BYTE detachedSignedContent[] = {
13050x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
13060x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
13070x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
13080x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
13090x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
13100x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
13110x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
13120x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
13130x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
13140x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
13150x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
13160xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1317static const BYTE signedBareContent[] = {
13180x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
13190x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
13200xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
13210x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
13220x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
13230x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
13240x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
13250x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
13260xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
13270x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
13280xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1329static const BYTE signedContent[] = {
13300x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
13310x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
13320x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
13330x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
13340x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
13350x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
13360x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
13370x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
13380xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
13390x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
13400x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
13410xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
13420x0d };
1343static const BYTE signedHash[] = {
13440x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
13450x2f };
1346static const BYTE signedKeyIdEmptyContent[] = {
13470x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
13480x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
13490xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
13500x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
13510x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1352static const BYTE signedEncodedSigner[] = {
13530x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
13540x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
13550x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
13560x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
13570x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
13580xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
13590x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
13600xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1361static const BYTE signedWithAuthAttrsBareContent[] = {
13620x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
13630x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
13640x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
13650x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
13660x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
13670x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
13680x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
13690xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
13700x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
13710x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
13720x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
13730x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
13740xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
13750x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
13760xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
13770x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
13780x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
13790xff,0xc6,0x33,0x63,0x34 };
1380static BYTE cert[] = {
13810x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
13820x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
13830x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
13840x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
13850x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
13860x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
13870x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
13880x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
13890xff,0x02,0x01,0x01 };
1390static BYTE v1CertWithPubKey[] = {
13910x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
13920x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
13930x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
13940x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
13950x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
13960x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
13970x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
13980x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
13990x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
14000x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
14010x01,0x01 };
1402static const BYTE signedWithCertEmptyBareContent[] = {
14030x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
14040x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
14050x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
14060x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
14070x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
14080x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
14090x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
14100x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
14110x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
14120x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
14130x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
14140x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
14150x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
14160xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1417static const BYTE signedWithCertBareContent[] = {
14180x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
14190x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
14200x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
14210x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
14220x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
14230x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
14240x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
14250x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
14260x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
14270x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
14280x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
14290x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
14300x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
14310x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
14320x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
14330x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
14340x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
14350xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
14360xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
14370xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1438static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
14390x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
14400x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
14410x30,0x30,0x30,0x30,0x5a };
1442static const BYTE signedWithCrlEmptyBareContent[] = {
14430x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
14440x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
14450x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
14460x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
14470x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
14480x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
14490x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
14500x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
14510x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1452static const BYTE signedWithCrlBareContent[] = {
14530x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
14540x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
14550xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
14560x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
14570x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
14580x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
14590x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
14600x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
14610x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
14620x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
14630x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
14640x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
14650xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
14660x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
14670xa8,0x0d };
1468static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
14690x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
14700x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
14710x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
14720x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
14730x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
14740x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
14750x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
14760x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
14770x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
14780x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
14790x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
14800x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
14810x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
14820x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
14830x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
14840x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
14850x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
14860x04,0x00 };
1487static const BYTE signedWithCertAndCrlBareContent[] = {
14880x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
14890x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
14900x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
14910x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
14920x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
14930x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
14940x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
14950x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
14960x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
14970x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
14980x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
14990x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
15000x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
15010x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
15020x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
15030x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
15040x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
15050x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
15060x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
15070xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
15080xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
15090x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
15100x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1511static const BYTE signedWithCertWithPubKeyBareContent[] = {
15120x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
15130x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
15140x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
15150x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
15160x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
15170x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
15180x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
15190x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
15200x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
15210x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
15220x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
15230x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
15240x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
15250x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
15260x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
15270x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1528static BYTE v1CertWithValidPubKey[] = {
15290x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
15300x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
15310x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
15320x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
15330x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
15340x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
15350x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
15360x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
15370xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
15380x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
15390xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
15400x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
15410x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
15420x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1543static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
15440x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
15450xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
15460x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
15470x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
15480x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
15490x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
15500x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
15510x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
15520x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
15530x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
15540x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
15550x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
15560x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
15570x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
15580xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
15590x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
15600x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
15610xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
15620x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
15630x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
15640x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
15650x00 };
1566static const BYTE signedWithCertWithValidPubKeyContent[] = {
15670x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
15680xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
15690x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
15700x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
15710x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
15720x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
15730x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
15740x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
15750x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
15760x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
15770x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
15780x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
15790x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
15800x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
15810x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
15820x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
15830x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
15840x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
15850x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
15860x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
15870x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
15880x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
15890x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
15900xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
15910xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
15920x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
15930x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1594
1595static void test_signed_msg_encoding(void)
1596{
1597 HCRYPTMSG msg;
1598 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1599 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1600 CERT_INFO certInfo = { 0 };
1601 CERT_BLOB encodedCert = { sizeof(cert), cert };
1602 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1603 char oid_common_name[] = szOID_COMMON_NAME;
1604 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1605 encodedCommonName };
1606 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1607 BOOL ret;
1608 HCRYPTKEY key;
1609 DWORD size;
1610
1611 certInfo.SerialNumber.cbData = sizeof(serialNum);
1612 certInfo.SerialNumber.pbData = serialNum;
1613 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1614 certInfo.Issuer.pbData = encodedCommonName;
1615 signer.pCertInfo = &certInfo;
1616 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1617 signInfo.cSigners = 1;
1618 signInfo.rgSigners = &signer;
1619
1620 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1621 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1622 if (!ret && GetLastError() == NTE_EXISTS) {
1623 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1624 PROV_RSA_FULL, 0);
1625 }
1626 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1627
1628 if (!ret) {
1629 skip("No context for tests\n");
1630 return;
1631 }
1632
1633 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1634 0, 0, &key);
1635 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1636
1637 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1638 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1639 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1640
1641 check_param("detached signed empty bare content", msg,
1642 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1643 sizeof(signedEmptyBareContent));
1644 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1645 signedEmptyContent, sizeof(signedEmptyContent));
1646 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1647 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1648 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1649 signedHash, sizeof(signedHash));
1650 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1651 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1652 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1653 detachedSignedContent, sizeof(detachedSignedContent));
1654 SetLastError(0xdeadbeef);
1655 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1656 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1657 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1658 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1659 signedEncodedSigner, sizeof(signedEncodedSigner));
1660
1661 CryptMsgClose(msg);
1662
1663 certInfo.SerialNumber.cbData = 0;
1664 certInfo.Issuer.cbData = 0;
1665 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1666 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1667 U(signer.SignerId).KeyId.pbData = (BYTE *)serialNum;
1668 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1669 NULL, NULL);
1670 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1671 check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM,
1672 signedKeyIdEmptyContent, sizeof(signedKeyIdEmptyContent));
1673 CryptMsgClose(msg);
1674
1675 certInfo.SerialNumber.cbData = sizeof(serialNum);
1676 certInfo.SerialNumber.pbData = serialNum;
1677 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1678 certInfo.Issuer.pbData = encodedCommonName;
1679 signer.SignerId.dwIdChoice = 0;
1680 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1681 NULL, NULL);
1682 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1683
1684 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1685 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1686 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1687 signedEmptyContent, sizeof(signedEmptyContent));
1688 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1689 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1690 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1691 signedBareContent, sizeof(signedBareContent));
1692 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1693 signedContent, sizeof(signedContent));
1694
1695 CryptMsgClose(msg);
1696
1697 signer.cAuthAttr = 1;
1698 signer.rgAuthAttr = &attr;
1699 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1700 NULL, NULL);
1701 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1702
1703 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1704 check_param("signed with auth attrs bare content", msg,
1705 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1706 sizeof(signedWithAuthAttrsBareContent));
1707
1708 CryptMsgClose(msg);
1709
1710 signer.cAuthAttr = 0;
1711 signInfo.rgCertEncoded = &encodedCert;
1712 signInfo.cCertEncoded = 1;
1713 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1714 NULL, NULL);
1715 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1716
1717 check_param("signed with cert empty bare content", msg,
1718 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1719 sizeof(signedWithCertEmptyBareContent));
1720 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1721 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1722 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1723 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1724
1725 CryptMsgClose(msg);
1726
1727 signInfo.cCertEncoded = 0;
1728 signInfo.rgCrlEncoded = &encodedCrl;
1729 signInfo.cCrlEncoded = 1;
1730 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1731 NULL, NULL);
1732 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1733
1734 check_param("signed with crl empty bare content", msg,
1735 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1736 sizeof(signedWithCrlEmptyBareContent));
1737 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1738 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1739 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1740 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1741
1742 CryptMsgClose(msg);
1743
1744 signInfo.cCertEncoded = 1;
1745 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1746 NULL, NULL);
1747 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1748
1749 check_param("signed with cert and crl empty bare content", msg,
1750 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1751 sizeof(signedWithCertAndCrlEmptyBareContent));
1752 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1753 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1754 check_param("signed with cert and crl bare content", msg,
1755 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1756 sizeof(signedWithCertAndCrlBareContent));
1757
1758 CryptMsgClose(msg);
1759
1760 /* Test with a cert with a (bogus) public key */
1761 signInfo.cCrlEncoded = 0;
1762 encodedCert.cbData = sizeof(v1CertWithPubKey);
1763 encodedCert.pbData = v1CertWithPubKey;
1764 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1765 NULL, NULL);
1766 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1767 check_param("signedWithCertWithPubKeyBareContent", msg,
1768 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1769 sizeof(signedWithCertWithPubKeyBareContent));
1770 CryptMsgClose(msg);
1771
1772 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1773 encodedCert.pbData = v1CertWithValidPubKey;
1774 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1775 NULL, NULL);
1776 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1777 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1778 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1779 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1780 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1781 check_param("signedWithCertWithValidPubKeyContent", msg,
1782 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1783 sizeof(signedWithCertWithValidPubKeyContent));
1784 CryptMsgClose(msg);
1785
1786 CryptDestroyKey(key);
1787 CryptReleaseContext(signer.hCryptProv, 0);
1788 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1789 CRYPT_DELETEKEYSET);
1790}
1791
1792static void test_signed_msg_get_param(void)
1793{
1794 BOOL ret;
1795 HCRYPTMSG msg;
1796 DWORD size, value = 0;
1797 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1798 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1799 CERT_INFO certInfo = { 0 };
1800
1801 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1802 NULL, NULL);
1803 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1804
1805 /* Content and bare content are always gettable */
1806 size = 0;
1807 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1808 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1809 size = 0;
1810 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1811 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1812 /* For "signed" messages, so is the version. */
1813 size = 0;
1814 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1815 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1816 size = sizeof(value);
1817 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1818 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1819 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1820 /* But for this message, with no signers, the hash and signer aren't
1821 * available.
1822 */
1823 size = 0;
1824 SetLastError(0xdeadbeef);
1825 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1826 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1827 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1828 SetLastError(0xdeadbeef);
1829 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1830 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1831 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1832 /* As usual, the type isn't available. */
1833 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1834 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1835 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1836
1837 CryptMsgClose(msg);
1838
1839 certInfo.SerialNumber.cbData = sizeof(serialNum);
1840 certInfo.SerialNumber.pbData = serialNum;
1841 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1842 certInfo.Issuer.pbData = encodedCommonName;
1843 signer.pCertInfo = &certInfo;
1844 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1845 signInfo.cSigners = 1;
1846 signInfo.rgSigners = &signer;
1847
1848 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1849 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1850 if (!ret && GetLastError() == NTE_EXISTS) {
1851 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1852 PROV_RSA_FULL, 0);
1853 }
1854 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1855
1856 if (!ret) {
1857 skip("No context for tests\n");
1858 return;
1859 }
1860
1861 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1862 NULL, NULL);
1863 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1864
1865 /* This message, with one signer, has the hash and signer for index 0
1866 * available, but not for other indexes.
1867 */
1868 size = 0;
1869 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1870 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1871 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1872 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1873 size = 0;
1874 SetLastError(0xdeadbeef);
1875 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1876 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1877 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1878 SetLastError(0xdeadbeef);
1879 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1880 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1881 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1882 /* As usual, the type isn't available. */
1883 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1884 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1885 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1886
1887 CryptMsgClose(msg);
1888
1889 /* Opening the message using the CMS fields.. */
1890 certInfo.SerialNumber.cbData = 0;
1891 certInfo.Issuer.cbData = 0;
1892 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1893 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1894 sizeof(encodedCommonName);
1895 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData =
1896 (BYTE *)encodedCommonName;
1897 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1898 sizeof(serialNum);
1899 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
1900 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1901 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1902 if (!ret && GetLastError() == NTE_EXISTS)
1903 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1904 PROV_RSA_FULL, 0);
1905 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1906 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1907 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1908 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1909 /* still results in the version being 1 when the issuer and serial number
1910 * are used and no additional CMS fields are used.
1911 */
1912 size = sizeof(value);
1913 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1914 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1915 ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value);
1916 /* Apparently the encoded signer can be retrieved.. */
1917 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1918 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1919 /* but the signer info, CMS signer info, and cert ID can't be. */
1920 SetLastError(0xdeadbeef);
1921 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1922 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1923 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1924 SetLastError(0xdeadbeef);
1925 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1926 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1927 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1928 SetLastError(0xdeadbeef);
1929 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1930 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1931 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1932 CryptMsgClose(msg);
1933
1934 /* Using the KeyId field of the SignerId results in the version becoming
1935 * the CMS version.
1936 */
1937 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1938 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1939 U(signer.SignerId).KeyId.pbData = (BYTE *)serialNum;
1940 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1941 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1942 if (!ret && GetLastError() == NTE_EXISTS)
1943 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1944 PROV_RSA_FULL, 0);
1945 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1946 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1947 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1948 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1949 size = sizeof(value);
1950 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1951 ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value);
1952 /* Even for a CMS message, the signer can be retrieved.. */
1953 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1954 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1955 /* but the signer info, CMS signer info, and cert ID can't be. */
1956 SetLastError(0xdeadbeef);
1957 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1958 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1959 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1960 SetLastError(0xdeadbeef);
1961 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1962 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1963 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1964 SetLastError(0xdeadbeef);
1965 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1966 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1967 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1968 CryptMsgClose(msg);
1969
1970 CryptReleaseContext(signer.hCryptProv, 0);
1971 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1972 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1973}
1974
1975static void test_signed_msg(void)
1976{
1977 test_signed_msg_open();
1978 test_signed_msg_update();
1979 test_signed_msg_encoding();
1980 test_signed_msg_get_param();
1981}
1982
1983static CRYPT_DATA_BLOB b4 = { 0, NULL };
1984static const struct update_accum a4 = { 1, &b4 };
1985
1986static const BYTE bogusOIDContent[] = {
19870x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
19880x04,0x00 };
1989static const BYTE bogusHashContent[] = {
19900x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
19910x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
19920x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
19930x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
19940x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1995
1996static void test_decode_msg_update(void)
1997{
1998 HCRYPTMSG msg;
1999 BOOL ret;
2000 CMSG_STREAM_INFO streamInfo = { 0 };
2001 DWORD i;
2002 struct update_accum accum = { 0, NULL };
2003
2004 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2005 /* Update with a full message in a final update */
2006 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2007 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2008 /* Can't update after a final update */
2009 SetLastError(0xdeadbeef);
2010 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2011 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2012 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2013 CryptMsgClose(msg);
2014
2015 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2016 /* Can't send a non-final update without streaming */
2017 SetLastError(0xdeadbeef);
2018 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2019 FALSE);
2020 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2021 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2022 /* A subsequent final update succeeds */
2023 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2024 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2025 CryptMsgClose(msg);
2026
2027 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2028 /* Updating a message that has a NULL stream callback fails */
2029 SetLastError(0xdeadbeef);
2030 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2031 FALSE);
2032 todo_wine
2033 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2034 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2035 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2036 GetLastError());
2037 /* Changing the callback pointer after the fact yields the same error (so
2038 * the message must copy the stream info, not just store a pointer to it)
2039 */
2040 streamInfo.pfnStreamOutput = nop_stream_output;
2041 SetLastError(0xdeadbeef);
2042 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2043 FALSE);
2044 todo_wine
2045 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2046 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2047 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2048 GetLastError());
2049 CryptMsgClose(msg);
2050
2051 /* Empty non-final updates are allowed when streaming.. */
2052 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2053 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2054 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2055 /* but final updates aren't when not enough data has been received. */
2056 SetLastError(0xdeadbeef);
2057 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2058 todo_wine
2059 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2060 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2061 CryptMsgClose(msg);
2062
2063 /* Updating the message byte by byte is legal */
2064 streamInfo.pfnStreamOutput = accumulating_stream_output;
2065 streamInfo.pvArg = &accum;
2066 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2067 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2068 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2069 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2070 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2071 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2072 CryptMsgClose(msg);
2073 todo_wine
2074 check_updates("byte-by-byte empty content", &a4, &accum);
2075 free_updates(&accum);
2076
2077 /* Decoding bogus content fails in non-streaming mode.. */
2078 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2079 SetLastError(0xdeadbeef);
2080 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2081 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2082 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2083 CryptMsgClose(msg);
2084 /* and as the final update in streaming mode.. */
2085 streamInfo.pfnStreamOutput = nop_stream_output;
2086 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2087 SetLastError(0xdeadbeef);
2088 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2089 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2090 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2091 CryptMsgClose(msg);
2092 /* and even as a non-final update in streaming mode. */
2093 streamInfo.pfnStreamOutput = nop_stream_output;
2094 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2095 SetLastError(0xdeadbeef);
2096 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2097 todo_wine
2098 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2099 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2100 CryptMsgClose(msg);
2101
2102 /* An empty message can be opened with undetermined type.. */
2103 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2104 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2105 TRUE);
2106 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2107 CryptMsgClose(msg);
2108 /* but decoding it as an explicitly typed message fails. */
2109 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2110 NULL);
2111 SetLastError(0xdeadbeef);
2112 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2113 TRUE);
2114 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2115 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2116 CryptMsgClose(msg);
2117 /* On the other hand, decoding the bare content of an empty message fails
2118 * with unspecified type..
2119 */
2120 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2121 SetLastError(0xdeadbeef);
2122 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2123 sizeof(dataEmptyBareContent), TRUE);
2124 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2125 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2126 CryptMsgClose(msg);
2127 /* but succeeds with explicit type. */
2128 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2129 NULL);
2130 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2131 sizeof(dataEmptyBareContent), TRUE);
2132 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2133 CryptMsgClose(msg);
2134
2135 /* Decoding valid content with an unsupported OID fails */
2136 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2137 SetLastError(0xdeadbeef);
2138 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2139 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2140 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2141 CryptMsgClose(msg);
2142
2143 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2144 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2145 SetLastError(0xdeadbeef);
2146 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2147 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2148 CryptMsgClose(msg);
2149 /* while with specified type it fails. */
2150 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2151 NULL);
2152 SetLastError(0xdeadbeef);
2153 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2154 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2155 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2156 CryptMsgClose(msg);
2157 /* On the other hand, decoding the bare content of an empty hash message
2158 * fails with unspecified type..
2159 */
2160 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2161 SetLastError(0xdeadbeef);
2162 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2163 sizeof(hashEmptyBareContent), TRUE);
2164 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2165 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2166 CryptMsgClose(msg);
2167 /* but succeeds with explicit type. */
2168 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2169 NULL);
2170 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2171 sizeof(hashEmptyBareContent), TRUE);
2172 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2173 CryptMsgClose(msg);
2174
2175 /* And again, opening a (non-empty) hash message with unspecified type
2176 * succeeds..
2177 */
2178 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2179 SetLastError(0xdeadbeef);
2180 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2181 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2182 CryptMsgClose(msg);
2183 /* while with specified type it fails.. */
2184 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2185 NULL);
2186 SetLastError(0xdeadbeef);
2187 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2188 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2189 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2190 CryptMsgClose(msg);
2191 /* and decoding the bare content of a non-empty hash message fails with
2192 * unspecified type..
2193 */
2194 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2195 SetLastError(0xdeadbeef);
2196 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2197 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2198 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2199 CryptMsgClose(msg);
2200 /* but succeeds with explicit type. */
2201 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2202 NULL);
2203 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2204 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2205 CryptMsgClose(msg);
2206
2207 /* Opening a (non-empty) hash message with unspecified type and a bogus
2208 * hash value succeeds..
2209 */
2210 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2211 SetLastError(0xdeadbeef);
2212 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2213 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2214 CryptMsgClose(msg);
2215
2216 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2217 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2218 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2219 CryptMsgClose(msg);
2220 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2221 SetLastError(0xdeadbeef);
2222 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2223 sizeof(signedWithCertAndCrlBareContent), TRUE);
2224 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2225 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2226 CryptMsgClose(msg);
2227 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2228 NULL);
2229 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2230 sizeof(signedWithCertAndCrlBareContent), TRUE);
2231 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2232 CryptMsgClose(msg);
2233
2234 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2235 NULL, NULL);
2236 /* The first update succeeds.. */
2237 ret = CryptMsgUpdate(msg, detachedSignedContent,
2238 sizeof(detachedSignedContent), TRUE);
2239 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2240 /* as does a second (probably to update the detached portion).. */
2241 ret = CryptMsgUpdate(msg, detachedSignedContent,
2242 sizeof(detachedSignedContent), TRUE);
2243 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2244 /* while a third fails. */
2245 ret = CryptMsgUpdate(msg, detachedSignedContent,
2246 sizeof(detachedSignedContent), TRUE);
2247 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2248 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2249 CryptMsgClose(msg);
2250
2251 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2252 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2253 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2254 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2255 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2256 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2257 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2258 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2259 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2260
2261 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2262 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2263 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2264 CryptMsgClose(msg);
2265}
2266
2267static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2268 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2269
2270static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2271 const CMSG_SIGNER_INFO *expected)
2272{
2273 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2274 expected->dwVersion, got->dwVersion);
2275 ok(got->Issuer.cbData == expected->Issuer.cbData,
2276 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2277 got->Issuer.cbData);
2278 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2279 "Unexpected issuer\n");
2280 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2281 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2282 got->SerialNumber.cbData);
2283 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2284 got->SerialNumber.cbData), "Unexpected serial number\n");
2285 /* FIXME: check more things */
2286}
2287
2288static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2289 const CMSG_CMS_SIGNER_INFO *expected)
2290{
2291 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2292 expected->dwVersion, got->dwVersion);
2293 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2294 "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2295 got->SignerId.dwIdChoice);
2296 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2297 {
2298 if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2299 {
2300 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2301 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2302 "Expected issuer size %d, got %d\n",
2303 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2304 U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2305 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2306 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2307 U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2308 "Unexpected issuer\n");
2309 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2310 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2311 "Expected serial number size %d, got %d\n",
2312 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2313 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2314 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2315 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2316 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2317 "Unexpected serial number\n");
2318 }
2319 else
2320 {
2321 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2322 "expected key id size %d, got %d\n",
2323 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2324 ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2325 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2326 "unexpected key id\n");
2327 }
2328 }
2329 /* FIXME: check more things */
2330}
2331
2332static const BYTE signedWithCertAndCrlComputedHash[] = {
23330x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
23340x2f };
2335static BYTE keyIdIssuer[] = {
23360x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
23370x0a,0x07,0x01,0x04,0x01,0x01 };
2338
2339static void test_decode_msg_get_param(void)
2340{
2341 HCRYPTMSG msg;
2342 BOOL ret;
2343 DWORD size = 0, value;
2344 LPBYTE buf;
2345
2346 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2347 SetLastError(0xdeadbeef);
2348 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2349 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2350 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2351 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2352 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2353 sizeof(msgData));
2354 CryptMsgClose(msg);
2355
2356 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2357 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2358 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2359 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2360 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2361 emptyHashParam, sizeof(emptyHashParam));
2362 CryptMsgClose(msg);
2363 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2364 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2365 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2366 sizeof(msgData));
2367 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2368 sizeof(hashParam));
2369 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2370 hashParam, sizeof(hashParam));
2371 /* Curiously, getting the hash of index 1 succeeds, even though there's
2372 * only one hash.
2373 */
2374 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2375 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2376 buf = CryptMemAlloc(size);
2377 if (buf)
2378 {
2379 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2380 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2381 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2382 CryptMemFree(buf);
2383 }
2384 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2385 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2386 value = CMSG_HASHED_DATA_V0;
2387 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2388 sizeof(value));
2389 CryptMsgClose(msg);
2390
2391 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2392 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2393 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2394 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2395 sizeof(msgData));
2396 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2397 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2398 size = sizeof(value);
2399 value = 2112;
2400 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2401 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2402 ok(value == 1, "Expected 1 signer, got %d\n", value);
2403 size = 0;
2404 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2405 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2406 if (ret)
2407 buf = CryptMemAlloc(size);
2408 else
2409 buf = NULL;
2410 if (buf)
2411 {
2412 CMSG_SIGNER_INFO signer = { 0 };
2413
2414 signer.dwVersion = 1;
2415 signer.Issuer.cbData = sizeof(encodedCommonName);
2416 signer.Issuer.pbData = encodedCommonName;
2417 signer.SerialNumber.cbData = sizeof(serialNum);
2418 signer.SerialNumber.pbData = serialNum;
2419 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2420 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2421 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2422 CryptMemFree(buf);
2423 }
2424 /* Getting the CMS signer info of a PKCS7 message is possible. */
2425 size = 0;
2426 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2427 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2428 if (ret)
2429 buf = CryptMemAlloc(size);
2430 else
2431 buf = NULL;
2432 if (buf)
2433 {
2434 CMSG_CMS_SIGNER_INFO signer = { 0 };
2435
2436 signer.dwVersion = 1;
2437 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2438 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2439 sizeof(encodedCommonName);
2440 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2441 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2442 sizeof(serialNum);
2443 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2444 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2445 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2446 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2447 CryptMemFree(buf);
2448 }
2449 /* index is ignored when getting signer count */
2450 size = sizeof(value);
2451 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2452 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2453 ok(value == 1, "Expected 1 signer, got %d\n", value);
2454 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2455 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2456 ok(value == 0, "Expected 0 certs, got %d\n", value);
2457 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2458 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2459 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2460 CryptMsgClose(msg);
2461 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2462 NULL);
2463 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2464 sizeof(signedWithCertAndCrlBareContent), TRUE);
2465 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2466 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2467 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2468 ok(value == 1, "Expected 1 cert, got %d\n", value);
2469 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2470 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2471 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2472 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2473 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2474 check_param("signed with cert and CRL computed hash", msg,
2475 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2476 sizeof(signedWithCertAndCrlComputedHash));
2477 CryptMsgClose(msg);
2478
2479 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2480 ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
2481 sizeof(signedKeyIdEmptyContent), TRUE);
2482 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2483 size = sizeof(value);
2484 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2485 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2486 ok(value == 1, "Expected 1 signer, got %d\n", value);
2487 /* Getting the regular (non-CMS) signer info from a CMS message is also
2488 * possible..
2489 */
2490 size = 0;
2491 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2492 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2493 if (ret)
2494 buf = CryptMemAlloc(size);
2495 else
2496 buf = NULL;
2497 if (buf)
2498 {
2499 CMSG_SIGNER_INFO signer;
2500 BYTE zero = 0;
2501
2502 /* and here's the little oddity: for a CMS message using the key id
2503 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
2504 * a signer with a zero (not empty) serial number, and whose issuer is
2505 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
2506 * and value of the key id.
2507 */
2508 signer.dwVersion = CMSG_SIGNED_DATA_V3;
2509 signer.Issuer.cbData = sizeof(keyIdIssuer);
2510 signer.Issuer.pbData = keyIdIssuer;
2511 signer.SerialNumber.cbData = 1;
2512 signer.SerialNumber.pbData = &zero;
2513 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2514 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2515 CryptMemFree(buf);
2516 }
2517 size = 0;
2518 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2519 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2520 if (ret)
2521 buf = CryptMemAlloc(size);
2522 else
2523 buf = NULL;
2524 if (buf)
2525 {
2526 CMSG_CMS_SIGNER_INFO signer = { 0 };
2527
2528 signer.dwVersion = CMSG_SIGNED_DATA_V3;
2529 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2530 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
2531 U(signer.SignerId).KeyId.pbData = (BYTE *)serialNum;
2532 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2533 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2534 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2535 CryptMemFree(buf);
2536 }
2537 CryptMsgClose(msg);
2538}
2539
2540static void test_decode_msg(void)
2541{
2542 test_decode_msg_update();
2543 test_decode_msg_get_param();
2544}
2545
2546static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2547/* aKey encoded as a X509_PUBLIC_KEY_INFO */
2548static BYTE encodedPubKey[] = {
25490x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
25500x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
25510x0d,0x0e,0x0f };
2552/* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2553static BYTE mod_encoded[] = {
2554 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2555 0x01,0x00,0x01 };
2556
2557static void test_msg_control(void)
2558{
2559 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2560 BOOL ret;
2561 HCRYPTMSG msg;
2562 DWORD i;
2563 CERT_INFO certInfo = { 0 };
2564 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2565 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2566 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2567
2568 /* Crashes
2569 ret = CryptMsgControl(NULL, 0, 0, NULL);
2570 */
2571
2572 /* Data encode messages don't allow any sort of control.. */
2573 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2574 NULL);
2575 /* either with no prior update.. */
2576 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2577 {
2578 SetLastError(0xdeadbeef);
2579 ret = CryptMsgControl(msg, 0, i, NULL);
2580 ok(!ret && GetLastError() == E_INVALIDARG,
2581 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2582 }
2583 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2584 /* or after an update. */
2585 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2586 {
2587 SetLastError(0xdeadbeef);
2588 ret = CryptMsgControl(msg, 0, i, NULL);
2589 ok(!ret && GetLastError() == E_INVALIDARG,
2590 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2591 }
2592 CryptMsgClose(msg);
2593
2594 /* Hash encode messages don't allow any sort of control.. */
2595 hashInfo.cbSize = sizeof(hashInfo);
2596 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2597 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2598 NULL, NULL);
2599 /* either with no prior update.. */
2600 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2601 {
2602 SetLastError(0xdeadbeef);
2603 ret = CryptMsgControl(msg, 0, i, NULL);
2604 ok(!ret && GetLastError() == E_INVALIDARG,
2605 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2606 }
2607 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2608 /* or after an update. */
2609 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2610 {
2611 SetLastError(0xdeadbeef);
2612 ret = CryptMsgControl(msg, 0, i, NULL);
2613 ok(!ret && GetLastError() == E_INVALIDARG,
2614 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2615 }
2616 CryptMsgClose(msg);
2617
2618 /* Signed encode messages likewise don't allow any sort of control.. */
2619 signInfo.cbSize = sizeof(signInfo);
2620 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2621 NULL, NULL);
2622 /* either before an update.. */
2623 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2624 {
2625 SetLastError(0xdeadbeef);
2626 ret = CryptMsgControl(msg, 0, i, NULL);
2627 ok(!ret && GetLastError() == E_INVALIDARG,
2628 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2629 }
2630 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2631 /* or after an update. */
2632 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2633 {
2634 SetLastError(0xdeadbeef);
2635 ret = CryptMsgControl(msg, 0, i, NULL);
2636 ok(!ret && GetLastError() == E_INVALIDARG,
2637 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2638 }
2639 CryptMsgClose(msg);
2640
2641 /* Decode messages behave a bit differently. */
2642 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2643 /* Bad control type */
2644 SetLastError(0xdeadbeef);
2645 ret = CryptMsgControl(msg, 0, 0, NULL);
2646 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2647 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2648 SetLastError(0xdeadbeef);
2649 ret = CryptMsgControl(msg, 1, 0, NULL);
2650 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2651 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2652 /* Can't verify the hash of an indeterminate-type message */
2653 SetLastError(0xdeadbeef);
2654 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2655 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2656 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2657 /* Crashes
2658 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2659 */
2660 /* Can't decrypt an indeterminate-type message */
2661 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2662 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2663 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2664 CryptMsgClose(msg);
2665
2666 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2667 NULL);
2668 /* Can't verify the hash of an empty message */
2669 SetLastError(0xdeadbeef);
2670 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2671 todo_wine
2672 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2673 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2674 /* Crashes
2675 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2676 */
2677 /* Can't verify the signature of a hash message */
2678 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2679 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2680 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2681 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2682 TRUE);
2683 /* Oddly enough, this fails */
2684 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2685 ok(!ret, "Expected failure\n");
2686 CryptMsgClose(msg);
2687 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2688 NULL);
2689 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2690 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2691 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2692 /* Can't decrypt an indeterminate-type message */
2693 SetLastError(0xdeadbeef);
2694 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2695 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2696 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2697 CryptMsgClose(msg);
2698
2699 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2700 NULL, NULL);
2701 /* Can't verify the hash of a detached message before it's been updated. */
2702 SetLastError(0xdeadbeef);
2703 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2704 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2705 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2706 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
2707 TRUE);
2708 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2709 /* Still can't verify the hash of a detached message with the content
2710 * of the detached hash given..
2711 */
2712 SetLastError(0xdeadbeef);
2713 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2714 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
2715 "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
2716 /* and giving the content of the message after attempting to verify the
2717 * hash fails.
2718 */
2719 SetLastError(0xdeadbeef);
2720 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2721 todo_wine
2722 ok(!ret &&
2723 (GetLastError() == NTE_BAD_HASH_STATE ||
2724 GetLastError() == NTE_BAD_ALGID || /* Win9x */
2725 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
2726 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
2727 "got %08x\n", GetLastError());
2728 CryptMsgClose(msg);
2729
2730 /* Finally, verifying the hash of a detached message in the correct order:
2731 * 1. Update with the detached hash message
2732 * 2. Update with the content of the message
2733 * 3. Verifying the hash of the message
2734 * succeeds.
2735 */
2736 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2737 NULL, NULL);
2738 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
2739 TRUE);
2740 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2741 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2742 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2743 SetLastError(0xdeadbeef);
2744 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2745 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2746 CryptMsgClose(msg);
2747
2748 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2749 NULL);
2750 /* Can't verify the hash of a signed message */
2751 SetLastError(0xdeadbeef);
2752 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2753 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2754 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2755 /* Can't decrypt a signed message */
2756 SetLastError(0xdeadbeef);
2757 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2758 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2759 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2760 /* Crash
2761 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2762 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2763 */
2764 CryptMsgUpdate(msg, signedWithCertBareContent,
2765 sizeof(signedWithCertBareContent), TRUE);
2766 /* With an empty cert info, the signer can't be found in the message (and
2767 * the signature can't be verified.
2768 */
2769 SetLastError(0xdeadbeef);
2770 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2771 ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2772 "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2773 /* The cert info is expected to have an issuer, serial number, and public
2774 * key info set.
2775 */
2776 certInfo.SerialNumber.cbData = sizeof(serialNum);
2777 certInfo.SerialNumber.pbData = serialNum;
2778 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2779 certInfo.Issuer.pbData = encodedCommonName;
2780 SetLastError(0xdeadbeef);
2781 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2782 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2783 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2784 CryptMsgClose(msg);
2785 /* This cert has a public key, but it's not in a usable form */
2786 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2787 NULL);
2788 CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2789 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2790 /* Again, cert info needs to have a public key set */
2791 SetLastError(0xdeadbeef);
2792 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2793 ok(!ret &&
2794 (GetLastError() == CRYPT_E_ASN1_EOD ||
2795 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2796 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2797 /* The public key is supposed to be in encoded form.. */
2798 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2799 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2800 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2801 SetLastError(0xdeadbeef);
2802 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2803 ok(!ret &&
2804 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2805 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2806 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2807 /* but not as a X509_PUBLIC_KEY_INFO.. */
2808 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2809 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2810 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2811 SetLastError(0xdeadbeef);
2812 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2813 ok(!ret &&
2814 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2815 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2816 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2817 /* This decodes successfully, but it doesn't match any key in the message */
2818 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2819 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2820 SetLastError(0xdeadbeef);
2821 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2822 /* In Wine's rsaenh, this fails to decode because the key length is too
2823 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
2824 * now.
2825 */
2826 todo_wine
2827 ok(!ret &&
2828 (GetLastError() == NTE_BAD_SIGNATURE ||
2829 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2830 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2831 CryptMsgClose(msg);
2832 /* A message with no data doesn't have a valid signature */
2833 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2834 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2835 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2836 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2837 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2838 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2839 SetLastError(0xdeadbeef);
2840 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2841 ok(!ret &&
2842 (GetLastError() == NTE_BAD_SIGNATURE ||
2843 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2844 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2845 CryptMsgClose(msg);
2846 /* Finally, this succeeds */
2847 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2848 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2849 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2850 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2851 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2852 CryptMsgClose(msg);
2853
2854 /* Test verifying signature of a detached signed message */
2855 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2856 NULL, NULL);
2857 ret = CryptMsgUpdate(msg, detachedSignedContent,
2858 sizeof(detachedSignedContent), TRUE);
2859 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2860 /* Can't verify the sig without having updated the data */
2861 SetLastError(0xdeadbeef);
2862 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2863 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2864 "expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2865 /* Now that the signature's been checked, can't do the final update */
2866 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2867 todo_wine
2868 ok(!ret &&
2869 (GetLastError() == NTE_BAD_HASH_STATE ||
2870 GetLastError() == NTE_BAD_ALGID || /* Win9x */
2871 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
2872 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
2873 "got %08x\n", GetLastError());
2874 CryptMsgClose(msg);
2875 /* Updating with the detached portion of the message and the data of the
2876 * the message allows the sig to be verified.
2877 */
2878 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2879 NULL, NULL);
2880 ret = CryptMsgUpdate(msg, detachedSignedContent,
2881 sizeof(detachedSignedContent), TRUE);
2882 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2883 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2884 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2885 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2886 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2887 CryptMsgClose(msg);
2888}
2889
2890/* win9x has much less parameter checks and will crash on many tests
2891 * this code is from test_signed_msg_update()
2892 */
2893static BOOL detect_nt(void)
2894{
2895 BOOL ret;
2896 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
2897 CERT_INFO certInfo = { 0 };
2898
2899 if (!pCryptAcquireContextW)
2900 return FALSE;
2901
2902 certInfo.SerialNumber.cbData = sizeof(serialNum);
2903 certInfo.SerialNumber.pbData = serialNum;
2904 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2905 certInfo.Issuer.pbData = encodedCommonName;
2906 signer.pCertInfo = &certInfo;
2907 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2908
2909 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2910 PROV_RSA_FULL, CRYPT_NEWKEYSET);
2911 if (!ret && GetLastError() == NTE_EXISTS) {
2912 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2913 PROV_RSA_FULL, 0);
2914 }
2915
2916 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
2917
2918 /* cleanup */
2919 CryptReleaseContext(signer.hCryptProv, 0);
2920 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
2921 CRYPT_DELETEKEYSET);
2922
2923 return TRUE;
2924}
2925
2926static void test_msg_get_and_verify_signer(void)
2927{
2928 BOOL ret;
2929 HCRYPTMSG msg;
2930 PCCERT_CONTEXT signer;
2931 DWORD signerIndex;
2932 HCERTSTORE store;
2933
2934 /* Crash */
2935 if (0)
2936 {
2937 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
2938 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
2939 }
2940
2941 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2942 /* An empty message has no signer */
2943 SetLastError(0xdeadbeef);
2944 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2945 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2946 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2947 /* The signer is cleared on error */
2948 signer = (PCCERT_CONTEXT)0xdeadbeef;
2949 SetLastError(0xdeadbeef);
2950 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2951 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2952 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2953 ok(!signer, "expected signer to be NULL\n");
2954 /* The signer index is also cleared on error */
2955 signerIndex = 0xdeadbeef;
2956 SetLastError(0xdeadbeef);
2957 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2958 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2959 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2960 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
2961 /* An unsigned message (msgData isn't a signed message at all)
2962 * likewise has no signer.
2963 */
2964 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2965 SetLastError(0xdeadbeef);
2966 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2967 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2968 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2969 CryptMsgClose(msg);
2970
2971 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2972 /* A "signed" message created with no signer cert likewise has no signer */
2973 CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
2974 SetLastError(0xdeadbeef);
2975 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2976 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2977 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2978 CryptMsgClose(msg);
2979
2980 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2981 /* A signed message succeeds, .. */
2982 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2983 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2984 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2985 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2986 /* the signer index can be retrieved, .. */
2987 signerIndex = 0xdeadbeef;
2988 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2989 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2990 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
2991 /* as can the signer cert. */
2992 signer = (PCCERT_CONTEXT)0xdeadbeef;
2993 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2994 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2995 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
2996 "expected a valid signer\n");
2997 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
2998 CertFreeCertificateContext(signer);
2999 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3000 */
3001 signerIndex = 0xdeadbeef;
3002 SetLastError(0xdeadbeef);
3003 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3004 NULL, &signerIndex);
3005 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3006 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3007 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3008 * message signer not to be found.
3009 */
3010 SetLastError(0xdeadbeef);
3011 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3012 NULL, NULL);
3013 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3014 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3015 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3016 * the message signer not to be found.
3017 */
3018 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3019 CERT_STORE_CREATE_NEW_FLAG, NULL);
3020 SetLastError(0xdeadbeef);
3021 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3022 NULL, NULL);
3023 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3024 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3025 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3026 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3027 CERT_STORE_ADD_ALWAYS, NULL);
3028 ok(ret, "CertAddEncodedCertificateToStore failed: 0x%08x\n",
3029 GetLastError());
3030 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3031 * the signer succeeds.
3032 */
3033 SetLastError(0xdeadbeef);
3034 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3035 NULL, NULL);
3036 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3037 CertCloseStore(store, 0);
3038 CryptMsgClose(msg);
3039}
3040
3041START_TEST(msg)
3042{
3043 init_function_pointers();
3044 have_nt = detect_nt();
3045
3046 /* Basic parameter checking tests */
3047 test_msg_open_to_encode();
3048 test_msg_open_to_decode();
3049 test_msg_get_param();
3050 test_msg_close();
3051 test_msg_control();
3052
3053 /* Message-type specific tests */
3054 test_data_msg();
3055 test_hash_msg();
3056 test_signed_msg();
3057 test_decode_msg();
3058
3059 test_msg_get_and_verify_signer();
3060}
Note: See TracBrowser for help on using the repository browser.