push 599a9d3db769aad8dabfd10a59120f719b00f4ee
[wine/hacks.git] / dlls / crypt32 / tests / msg.c
blob68487a51d811ce4959ab9ed6be515ebed75524aa
1 /*
2 * Unit test suite for crypt32.dll's CryptMsg functions
4 * Copyright 2007 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winerror.h>
26 #include <wincrypt.h>
28 #include "wine/test.h"
30 static char oid_rsa_md5[] = szOID_RSA_MD5;
32 static BOOL (WINAPI * pCryptAcquireContextW)
33 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
35 static void init_function_pointers(void)
37 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
39 #define GET_PROC(dll, func) \
40 p ## func = (void *)GetProcAddress(dll, #func); \
41 if(!p ## func) \
42 trace("GetProcAddress(%s) failed\n", #func);
44 GET_PROC(hAdvapi32, CryptAcquireContextW)
46 #undef GET_PROC
49 static void test_msg_open_to_encode(void)
51 HCRYPTMSG msg;
53 /* Crash
54 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
55 NULL, NULL);
56 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
57 NULL);
58 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
59 NULL);
62 /* Bad encodings */
63 SetLastError(0xdeadbeef);
64 msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
65 ok(!msg && GetLastError() == E_INVALIDARG,
66 "Expected E_INVALIDARG, got %x\n", GetLastError());
67 SetLastError(0xdeadbeef);
68 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
69 ok(!msg && GetLastError() == E_INVALIDARG,
70 "Expected E_INVALIDARG, got %x\n", GetLastError());
72 /* Bad message types */
73 SetLastError(0xdeadbeef);
74 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
75 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
76 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
77 SetLastError(0xdeadbeef);
78 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
79 NULL, NULL, NULL);
80 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
81 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
82 SetLastError(0xdeadbeef);
83 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
84 CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
85 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
86 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
87 SetLastError(0xdeadbeef);
88 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
89 NULL, NULL);
90 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
91 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
94 static void test_msg_open_to_decode(void)
96 HCRYPTMSG msg;
97 CMSG_STREAM_INFO streamInfo = { 0 };
99 SetLastError(0xdeadbeef);
100 msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
101 ok(!msg && GetLastError() == E_INVALIDARG,
102 "Expected E_INVALIDARG, got %x\n", GetLastError());
104 /* Bad encodings */
105 SetLastError(0xdeadbeef);
106 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
107 ok(!msg && GetLastError() == E_INVALIDARG,
108 "Expected E_INVALIDARG, got %x\n", GetLastError());
109 SetLastError(0xdeadbeef);
110 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
111 ok(!msg && GetLastError() == E_INVALIDARG,
112 "Expected E_INVALIDARG, got %x\n", GetLastError());
114 /* The message type can be explicit... */
115 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
116 NULL);
117 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
118 CryptMsgClose(msg);
119 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
120 NULL);
121 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
122 CryptMsgClose(msg);
123 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
124 NULL);
125 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
126 CryptMsgClose(msg);
127 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
128 NULL);
129 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
130 CryptMsgClose(msg);
131 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
132 CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
133 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
134 CryptMsgClose(msg);
135 /* or implicit.. */
136 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
137 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
138 CryptMsgClose(msg);
139 /* or even invalid. */
140 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
141 NULL);
142 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
143 CryptMsgClose(msg);
144 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
145 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
146 CryptMsgClose(msg);
148 /* And even though the stream info parameter "must be set to NULL" for
149 * CMSG_HASHED, it's still accepted.
151 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
152 &streamInfo);
153 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
154 CryptMsgClose(msg);
157 static void test_msg_get_param(void)
159 BOOL ret;
160 HCRYPTMSG msg;
161 DWORD size, i, value;
162 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
163 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
165 /* Crash
166 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
167 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
168 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
171 /* Decoded messages */
172 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
173 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
174 /* For decoded messages, the type is always available */
175 size = 0;
176 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
177 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
178 size = sizeof(value);
179 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
180 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
181 /* For this (empty) message, the type isn't set */
182 ok(value == 0, "Expected type 0, got %d\n", value);
183 CryptMsgClose(msg);
185 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
186 NULL);
187 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
188 /* For explicitly typed messages, the type is known. */
189 size = sizeof(value);
190 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
191 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
192 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
193 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
195 size = 0;
196 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
197 ok(!ret, "Parameter %d: expected failure\n", i);
199 CryptMsgClose(msg);
201 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
202 NULL);
203 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
204 size = sizeof(value);
205 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
206 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
207 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
208 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
210 size = 0;
211 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
212 ok(!ret, "Parameter %d: expected failure\n", i);
214 CryptMsgClose(msg);
216 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
217 NULL);
218 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
219 size = sizeof(value);
220 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
221 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
222 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
223 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
225 size = 0;
226 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
227 ok(!ret, "Parameter %d: expected failure\n", i);
229 CryptMsgClose(msg);
231 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
232 NULL);
233 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
234 size = sizeof(value);
235 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
236 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
237 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
238 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
240 size = 0;
241 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
242 ok(!ret, "Parameter %d: expected failure\n", i);
244 CryptMsgClose(msg);
246 /* Explicitly typed messages get their types set, even if they're invalid */
247 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
248 NULL);
249 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
250 size = sizeof(value);
251 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
252 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
253 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
254 CryptMsgClose(msg);
256 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
257 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
258 size = sizeof(value);
259 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
260 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
261 ok(value == 1000, "Expected 1000, got %d\n", value);
262 CryptMsgClose(msg);
265 static void test_msg_close(void)
267 BOOL ret;
268 HCRYPTMSG msg;
270 /* NULL succeeds.. */
271 ret = CryptMsgClose(NULL);
272 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
273 /* but an arbitrary pointer crashes. */
274 if (0)
275 ret = CryptMsgClose((HCRYPTMSG)1);
276 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
277 NULL);
278 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
279 ret = CryptMsgClose(msg);
280 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
283 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
284 const BYTE *expected, DWORD expectedSize)
286 DWORD size;
287 LPBYTE buf;
288 BOOL ret;
290 size = 0xdeadbeef;
291 ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
292 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
293 buf = HeapAlloc(GetProcessHeap(), 0, size);
294 ret = CryptMsgGetParam(msg, param, 0, buf, &size);
295 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
296 ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
297 expectedSize, size);
298 if (size == expectedSize && size)
299 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
300 HeapFree(GetProcessHeap(), 0, buf);
303 static void test_data_msg_open(void)
305 HCRYPTMSG msg;
306 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
307 CMSG_STREAM_INFO streamInfo = { 0 };
308 char oid[] = "1.2.3";
310 /* The data message type takes no additional info */
311 SetLastError(0xdeadbeef);
312 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
313 NULL, NULL);
314 ok(!msg && GetLastError() == E_INVALIDARG,
315 "Expected E_INVALIDARG, got %x\n", GetLastError());
316 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
317 NULL);
318 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
319 CryptMsgClose(msg);
321 /* An empty stream info is allowed. */
322 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
323 &streamInfo);
324 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
325 CryptMsgClose(msg);
327 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
328 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
329 NULL);
330 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
331 CryptMsgClose(msg);
332 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
333 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
334 CMSG_DATA, NULL, oid, NULL);
335 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
336 CryptMsgClose(msg);
337 /* and when a stream info is given, even though you're not supposed to be
338 * able to use anything but szOID_RSA_data when streaming is being used.
340 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
341 CMSG_DATA, NULL, oid, &streamInfo);
342 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
343 CryptMsgClose(msg);
346 static const BYTE msgData[] = { 1, 2, 3, 4 };
348 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
349 BOOL final)
351 return TRUE;
354 static void test_data_msg_update(void)
356 HCRYPTMSG msg;
357 BOOL ret;
358 CMSG_STREAM_INFO streamInfo = { 0 };
360 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
361 NULL);
362 /* Can't update a message that wasn't opened detached with final = FALSE */
363 SetLastError(0xdeadbeef);
364 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
365 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
366 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
367 /* Updating it with final = TRUE succeeds */
368 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
369 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
370 /* Any subsequent update will fail, as the last was final */
371 SetLastError(0xdeadbeef);
372 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
373 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
374 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
375 CryptMsgClose(msg);
377 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
378 NULL);
379 /* Can't update a message with no data */
380 SetLastError(0xdeadbeef);
381 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
382 ok(!ret && GetLastError() == E_INVALIDARG,
383 "Expected E_INVALIDARG, got %x\n", GetLastError());
384 /* Curiously, a valid update will now fail as well, presumably because of
385 * the last (invalid, but final) update.
387 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
388 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
389 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
390 CryptMsgClose(msg);
392 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
393 CMSG_DATA, NULL, NULL, NULL);
394 /* Doesn't appear to be able to update CMSG-DATA with non-final updates */
395 SetLastError(0xdeadbeef);
396 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
397 ok(!ret && GetLastError() == E_INVALIDARG,
398 "Expected E_INVALIDARG, got %x\n", GetLastError());
399 SetLastError(0xdeadbeef);
400 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
401 ok(!ret && GetLastError() == E_INVALIDARG,
402 "Expected E_INVALIDARG, got %x\n", GetLastError());
403 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
404 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
405 CryptMsgClose(msg);
407 /* Calling update after opening with an empty stream info (with a bogus
408 * output function) yields an error:
410 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
411 &streamInfo);
412 SetLastError(0xdeadbeef);
413 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
414 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
415 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
416 CryptMsgClose(msg);
417 /* Calling update with a valid output function succeeds, even if the data
418 * exceeds the size specified in the stream info.
420 streamInfo.pfnStreamOutput = nop_stream_output;
421 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
422 &streamInfo);
423 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
424 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
425 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
426 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
427 CryptMsgClose(msg);
430 static void test_data_msg_get_param(void)
432 HCRYPTMSG msg;
433 DWORD size;
434 BOOL ret;
435 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
437 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
438 NULL);
440 /* Content and bare content are always gettable when not streaming */
441 size = 0;
442 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
443 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
444 size = 0;
445 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
446 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
447 /* But for this type of message, the signer and hash aren't applicable,
448 * and the type isn't available.
450 size = 0;
451 SetLastError(0xdeadbeef);
452 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
453 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
454 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
455 SetLastError(0xdeadbeef);
456 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
457 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
458 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
459 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
460 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
461 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
462 CryptMsgClose(msg);
464 /* Can't get content or bare content when streaming */
465 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
466 NULL, &streamInfo);
467 SetLastError(0xdeadbeef);
468 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
469 ok(!ret && GetLastError() == E_INVALIDARG,
470 "Expected E_INVALIDARG, got %x\n", GetLastError());
471 SetLastError(0xdeadbeef);
472 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
473 ok(!ret && GetLastError() == E_INVALIDARG,
474 "Expected E_INVALIDARG, got %x\n", GetLastError());
475 CryptMsgClose(msg);
478 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
479 static const BYTE dataEmptyContent[] = {
480 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
481 0x04,0x00 };
482 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
483 static const BYTE dataContent[] = {
484 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
485 0x04,0x04,0x01,0x02,0x03,0x04 };
487 struct update_accum
489 DWORD cUpdates;
490 CRYPT_DATA_BLOB *updates;
493 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
494 DWORD cb, BOOL final)
496 struct update_accum *accum = (struct update_accum *)pvArg;
497 BOOL ret = FALSE;
499 if (accum->cUpdates)
500 accum->updates = CryptMemRealloc(accum->updates,
501 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
502 else
503 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
504 if (accum->updates)
506 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
508 blob->pbData = CryptMemAlloc(cb);
509 if (blob->pbData)
511 memcpy(blob->pbData, pb, cb);
512 blob->cbData = cb;
513 ret = TRUE;
515 accum->cUpdates++;
517 return ret;
520 /* The updates of a (bogus) definite-length encoded message */
521 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
522 0x07,0x01,0xa0,0x02,0x04,0x00 };
523 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
524 static CRYPT_DATA_BLOB b1[] = {
525 { sizeof(u1), u1 },
526 { sizeof(u2), u2 },
527 { sizeof(u2), u2 },
529 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
530 /* The updates of a definite-length encoded message */
531 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
532 0x07,0x01,0xa0,0x06,0x04,0x04 };
533 static CRYPT_DATA_BLOB b2[] = {
534 { sizeof(u3), u3 },
535 { sizeof(u2), u2 },
537 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
538 /* The updates of an indefinite-length encoded message */
539 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
540 0x07,0x01,0xa0,0x80,0x24,0x80 };
541 static BYTE u5[] = { 0x04,0x04 };
542 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
543 static CRYPT_DATA_BLOB b3[] = {
544 { sizeof(u4), u4 },
545 { sizeof(u5), u5 },
546 { sizeof(u2), u2 },
547 { sizeof(u5), u5 },
548 { sizeof(u2), u2 },
549 { sizeof(u6), u6 },
551 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
553 static void check_updates(LPCSTR header, const struct update_accum *expected,
554 const struct update_accum *got)
556 DWORD i;
558 ok(expected->cUpdates == got->cUpdates,
559 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
560 got->cUpdates);
561 if (expected->cUpdates == got->cUpdates)
562 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
564 ok(expected->updates[i].cbData == got->updates[i].cbData,
565 "%s, update %d: expected %d bytes, got %d\n", header, i,
566 expected->updates[i].cbData, got->updates[i].cbData);
567 if (expected->updates[i].cbData && expected->updates[i].cbData ==
568 got->updates[i].cbData)
569 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
570 got->updates[i].cbData), "%s, update %d: unexpected value\n",
571 header, i);
575 /* Frees the updates stored in accum */
576 static void free_updates(struct update_accum *accum)
578 DWORD i;
580 for (i = 0; i < accum->cUpdates; i++)
581 CryptMemFree(accum->updates[i].pbData);
582 CryptMemFree(accum->updates);
583 accum->updates = NULL;
584 accum->cUpdates = 0;
587 static void test_data_msg_encoding(void)
589 HCRYPTMSG msg;
590 BOOL ret;
591 static char oid[] = "1.2.3";
592 struct update_accum accum = { 0, NULL };
593 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
595 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
596 NULL);
597 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
598 dataEmptyBareContent, sizeof(dataEmptyBareContent));
599 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
600 sizeof(dataEmptyContent));
601 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
602 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
603 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
604 dataBareContent, sizeof(dataBareContent));
605 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
606 sizeof(dataContent));
607 CryptMsgClose(msg);
608 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
609 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
610 CMSG_DATA, NULL, NULL, NULL);
611 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
612 dataEmptyBareContent, sizeof(dataEmptyBareContent));
613 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
614 sizeof(dataEmptyContent));
615 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
616 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
617 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
618 dataBareContent, sizeof(dataBareContent));
619 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
620 sizeof(dataContent));
621 CryptMsgClose(msg);
622 /* The inner OID is apparently ignored */
623 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
624 NULL);
625 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
626 dataEmptyBareContent, sizeof(dataEmptyBareContent));
627 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
628 dataEmptyContent, sizeof(dataEmptyContent));
629 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
630 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
631 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
632 dataBareContent, sizeof(dataBareContent));
633 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
634 sizeof(dataContent));
635 CryptMsgClose(msg);
636 /* A streaming message is DER encoded if the length is not 0xffffffff, but
637 * curiously, updates aren't validated to make sure they don't exceed the
638 * stated length. (The resulting output will of course fail to decode.)
640 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
641 NULL, &streamInfo);
642 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
643 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
644 CryptMsgClose(msg);
645 check_updates("bogus data message with definite length", &a1, &accum);
646 free_updates(&accum);
647 /* A valid definite-length encoding: */
648 streamInfo.cbContent = sizeof(msgData);
649 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
650 NULL, &streamInfo);
651 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
652 CryptMsgClose(msg);
653 check_updates("data message with definite length", &a2, &accum);
654 free_updates(&accum);
655 /* An indefinite-length encoding: */
656 streamInfo.cbContent = 0xffffffff;
657 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
658 NULL, &streamInfo);
659 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
660 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
661 CryptMsgClose(msg);
662 todo_wine
663 check_updates("data message with indefinite length", &a3, &accum);
664 free_updates(&accum);
667 static void test_data_msg(void)
669 test_data_msg_open();
670 test_data_msg_update();
671 test_data_msg_get_param();
672 test_data_msg_encoding();
675 static void test_hash_msg_open(void)
677 HCRYPTMSG msg;
678 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
679 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
681 SetLastError(0xdeadbeef);
682 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
683 NULL, NULL);
684 ok(!msg && GetLastError() == E_INVALIDARG,
685 "Expected E_INVALIDARG, got %x\n", GetLastError());
686 hashInfo.cbSize = sizeof(hashInfo);
687 SetLastError(0xdeadbeef);
688 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
689 NULL, NULL);
690 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
691 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
692 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
693 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
694 NULL, NULL);
695 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
696 CryptMsgClose(msg);
697 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
698 CMSG_HASHED, &hashInfo, NULL, NULL);
699 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
700 CryptMsgClose(msg);
701 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
702 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
703 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
704 CryptMsgClose(msg);
707 static void test_hash_msg_update(void)
709 HCRYPTMSG msg;
710 BOOL ret;
711 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
712 { oid_rsa_md5, { 0, NULL } }, NULL };
713 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
715 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
716 CMSG_HASHED, &hashInfo, NULL, NULL);
717 /* Detached hashed messages opened in non-streaming mode allow non-final
718 * updates..
720 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
721 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
722 /* including non-final updates with no data.. */
723 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
724 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
725 /* and final updates with no data. */
726 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
727 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
728 /* But no updates are allowed after the final update. */
729 SetLastError(0xdeadbeef);
730 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
731 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
732 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
733 SetLastError(0xdeadbeef);
734 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
735 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
736 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
737 CryptMsgClose(msg);
738 /* Non-detached messages, in contrast, don't allow non-final updates in
739 * non-streaming mode.
741 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
742 NULL, NULL);
743 SetLastError(0xdeadbeef);
744 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
745 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
746 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
747 /* Final updates (including empty ones) are allowed. */
748 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
749 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
750 CryptMsgClose(msg);
751 /* And, of course, streaming mode allows non-final updates */
752 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
753 NULL, &streamInfo);
754 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
755 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
756 CryptMsgClose(msg);
757 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
758 * to be a bug, it isn't actually used - see encoding tests.)
760 streamInfo.pfnStreamOutput = NULL;
761 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
762 NULL, &streamInfo);
763 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
764 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
765 CryptMsgClose(msg);
768 static const BYTE emptyHashParam[] = {
769 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
770 0x7e };
772 static void test_hash_msg_get_param(void)
774 HCRYPTMSG msg;
775 BOOL ret;
776 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
777 { oid_rsa_md5, { 0, NULL } }, NULL };
778 DWORD size, value;
779 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
780 BYTE buf[16];
782 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
783 NULL, NULL);
784 /* Content and bare content are always gettable for non-streamed messages */
785 size = 0;
786 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
787 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
788 size = 0;
789 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
790 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
791 /* For an encoded hash message, the hash data aren't available */
792 SetLastError(0xdeadbeef);
793 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
794 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
795 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
796 /* The hash is also available. */
797 size = 0;
798 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
799 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
800 ok(size == sizeof(buf), "Unexpected size %d\n", size);
801 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
802 if (size == sizeof(buf))
803 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
804 /* By getting the hash, further updates are not allowed */
805 SetLastError(0xdeadbeef);
806 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
807 ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
808 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
809 /* Even after a final update, the hash data aren't available */
810 SetLastError(0xdeadbeef);
811 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
812 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
813 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
814 /* The version is also available, and should be zero for this message. */
815 size = 0;
816 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
817 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
818 size = sizeof(value);
819 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
820 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
821 ok(value == 0, "Expected version 0, got %d\n", value);
822 /* As usual, the type isn't available. */
823 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
824 ok(!ret, "Expected failure\n");
825 CryptMsgClose(msg);
827 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
828 NULL, &streamInfo);
829 /* Streamed messages don't allow you to get the content or bare content. */
830 SetLastError(0xdeadbeef);
831 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
832 ok(!ret && GetLastError() == E_INVALIDARG,
833 "Expected E_INVALIDARG, got %x\n", GetLastError());
834 SetLastError(0xdeadbeef);
835 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
836 ok(!ret && GetLastError() == E_INVALIDARG,
837 "Expected E_INVALIDARG, got %x\n", GetLastError());
838 /* The hash is still available. */
839 size = 0;
840 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
841 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
842 ok(size == sizeof(buf), "Unexpected size %d\n", size);
843 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
844 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
845 if (size == sizeof(buf))
846 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
847 /* After updating the hash, further updates aren't allowed on streamed
848 * messages either.
850 SetLastError(0xdeadbeef);
851 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
852 ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
853 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
854 CryptMsgClose(msg);
857 static const BYTE hashEmptyBareContent[] = {
858 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
859 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
860 static const BYTE hashEmptyContent[] = {
861 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
862 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
863 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
864 static const BYTE hashBareContent[] = {
865 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
866 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
867 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
868 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
869 static const BYTE hashContent[] = {
870 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
871 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
872 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
873 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
874 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
876 static const BYTE detachedHashNonFinalBareContent[] = {
877 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
878 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
879 0x07,0x01,0x04,0x00 };
880 static const BYTE detachedHashNonFinalContent[] = {
881 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
882 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
883 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
884 0x07,0x01,0x04,0x00 };
885 static const BYTE detachedHashBareContent[] = {
886 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
887 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
888 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
889 0x9d,0x2a,0x8f,0x26,0x2f };
890 static const BYTE detachedHashContent[] = {
891 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
892 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
893 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
894 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
895 0x9d,0x2a,0x8f,0x26,0x2f };
897 static void test_hash_msg_encoding(void)
899 HCRYPTMSG msg;
900 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
901 BOOL ret;
902 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
903 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
905 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
906 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
907 NULL, NULL);
908 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
909 hashEmptyBareContent, sizeof(hashEmptyBareContent));
910 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
911 hashEmptyContent, sizeof(hashEmptyContent));
912 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
913 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
914 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
915 hashBareContent, sizeof(hashBareContent));
916 check_param("hash content", msg, CMSG_CONTENT_PARAM,
917 hashContent, sizeof(hashContent));
918 CryptMsgClose(msg);
919 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
920 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
921 CMSG_HASHED, &hashInfo, NULL, NULL);
922 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
923 hashEmptyBareContent, sizeof(hashEmptyBareContent));
924 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
925 hashEmptyContent, sizeof(hashEmptyContent));
926 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
927 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
928 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
929 hashBareContent, sizeof(hashBareContent));
930 check_param("hash content", msg, CMSG_CONTENT_PARAM,
931 hashContent, sizeof(hashContent));
932 CryptMsgClose(msg);
933 /* Same test, but with CMSG_DETACHED_FLAG set */
934 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
935 CMSG_HASHED, &hashInfo, NULL, NULL);
936 check_param("detached hash empty bare content", msg,
937 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
938 sizeof(hashEmptyBareContent));
939 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
940 hashEmptyContent, sizeof(hashEmptyContent));
941 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
942 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
943 check_param("detached hash not final bare content", msg,
944 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
945 sizeof(detachedHashNonFinalBareContent));
946 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
947 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
948 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
949 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
950 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
951 detachedHashBareContent, sizeof(detachedHashBareContent));
952 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
953 detachedHashContent, sizeof(detachedHashContent));
954 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
955 detachedHashBareContent, sizeof(detachedHashBareContent));
956 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
957 detachedHashContent, sizeof(detachedHashContent));
958 CryptMsgClose(msg);
959 /* In what appears to be a bug, streamed updates to hash messages don't
960 * call the output function.
962 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
963 NULL, &streamInfo);
964 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
965 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
966 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
967 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
968 CryptMsgClose(msg);
969 check_updates("empty hash message", &empty_accum, &accum);
970 free_updates(&accum);
972 streamInfo.cbContent = sizeof(msgData);
973 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
974 NULL, &streamInfo);
975 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
976 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
977 CryptMsgClose(msg);
978 check_updates("hash message", &empty_accum, &accum);
979 free_updates(&accum);
981 streamInfo.cbContent = sizeof(msgData);
982 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
983 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
984 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
985 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
986 CryptMsgClose(msg);
987 check_updates("detached hash message", &empty_accum, &accum);
988 free_updates(&accum);
991 static void test_hash_msg(void)
993 test_hash_msg_open();
994 test_hash_msg_update();
995 test_hash_msg_get_param();
996 test_hash_msg_encoding();
999 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1000 'm','p',0 };
1001 static BYTE serialNum[] = { 1 };
1002 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1003 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1005 static void test_signed_msg_open(void)
1007 HCRYPTMSG msg;
1008 BOOL ret;
1009 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1010 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1011 CERT_INFO certInfo = { 0 };
1013 SetLastError(0xdeadbeef);
1014 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1015 NULL, NULL);
1016 ok(!msg && GetLastError() == E_INVALIDARG,
1017 "Expected E_INVALIDARG, got %x\n", GetLastError());
1018 signInfo.cbSize = sizeof(signInfo);
1019 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1020 NULL, NULL);
1021 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1022 CryptMsgClose(msg);
1024 signInfo.cSigners = 1;
1025 signInfo.rgSigners = &signer;
1026 /* With signer.pCertInfo unset, attempting to open this message this
1027 * crashes.
1029 signer.pCertInfo = &certInfo;
1030 /* The cert info must contain a serial number and an issuer. */
1031 SetLastError(0xdeadbeef);
1032 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1033 NULL, NULL);
1034 ok(!msg && GetLastError() == E_INVALIDARG,
1035 "Expected E_INVALIDARG, got %x\n", GetLastError());
1036 certInfo.SerialNumber.cbData = sizeof(serialNum);
1037 certInfo.SerialNumber.pbData = serialNum;
1038 SetLastError(0xdeadbeef);
1039 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1040 NULL, NULL);
1041 ok(!msg && GetLastError() == E_INVALIDARG,
1042 "Expected E_INVALIDARG, got %x\n", GetLastError());
1043 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1044 certInfo.Issuer.pbData = encodedCommonName;
1045 SetLastError(0xdeadbeef);
1046 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1047 NULL, NULL);
1048 ok(!msg && GetLastError() == E_INVALIDARG,
1049 "Expected E_INVALIDARG, got %x\n", GetLastError());
1051 /* The signer's hCryptProv must be set to something. Whether it's usable
1052 * or not will be checked after the hash algorithm is checked (see next
1053 * test.)
1055 signer.hCryptProv = 1;
1056 SetLastError(0xdeadbeef);
1057 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1058 NULL, NULL);
1059 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1060 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1061 /* The signer's hash algorithm must also be set. */
1062 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1063 SetLastError(0xdeadbeef);
1064 /* Crashes in advapi32 in wine, don't do it */
1065 if (0) {
1066 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1067 &signInfo, NULL, NULL);
1068 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1069 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1071 /* The signer's hCryptProv must also be valid. */
1072 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1073 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1074 if (!ret && GetLastError() == NTE_EXISTS)
1075 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1076 PROV_RSA_FULL, 0);
1077 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1078 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1079 NULL, NULL);
1080 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1081 CryptMsgClose(msg);
1083 CryptReleaseContext(signer.hCryptProv, 0);
1084 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1085 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1088 static const BYTE privKey[] = {
1089 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1090 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1091 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1092 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1093 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1094 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1095 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1096 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1097 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1098 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1099 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1100 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1101 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1102 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1103 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1104 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1105 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1106 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1107 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1108 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1109 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1110 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1111 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1112 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1113 static BYTE pubKey[] = {
1114 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1115 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1116 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1117 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1118 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1120 static void test_signed_msg_update(void)
1122 HCRYPTMSG msg;
1123 BOOL ret;
1124 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1125 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1126 CERT_INFO certInfo = { 0 };
1127 HCRYPTKEY key;
1129 certInfo.SerialNumber.cbData = sizeof(serialNum);
1130 certInfo.SerialNumber.pbData = serialNum;
1131 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1132 certInfo.Issuer.pbData = encodedCommonName;
1133 signer.pCertInfo = &certInfo;
1134 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1135 signInfo.cSigners = 1;
1136 signInfo.rgSigners = &signer;
1137 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1138 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1139 if (!ret && GetLastError() == NTE_EXISTS)
1140 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1141 PROV_RSA_FULL, 0);
1142 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1143 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1144 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1145 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1146 /* Detached CMSG_SIGNED allows non-final updates. */
1147 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1148 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1149 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1150 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1151 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1152 /* The final update requires a private key in the hCryptProv, in order to
1153 * generate the signature.
1155 SetLastError(0xdeadbeef);
1156 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1157 ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1158 GetLastError() == NTE_NO_KEY),
1159 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1160 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1161 0, 0, &key);
1162 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1163 /* The final update should be able to succeed now that a key exists, but
1164 * the previous (invalid) final update prevents it.
1166 SetLastError(0xdeadbeef);
1167 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1168 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1169 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1170 CryptMsgClose(msg);
1172 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1173 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1174 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1175 /* Detached CMSG_SIGNED allows non-final updates. */
1176 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1177 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1178 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1179 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1180 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1181 /* Now that the private key exists, the final update can succeed (even
1182 * with no data.)
1184 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1185 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1186 /* But no updates are allowed after the final update. */
1187 SetLastError(0xdeadbeef);
1188 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1189 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1190 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1191 SetLastError(0xdeadbeef);
1192 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1193 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1194 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1195 CryptMsgClose(msg);
1197 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1198 NULL, NULL);
1199 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1200 /* Non-detached messages don't allow non-final updates.. */
1201 SetLastError(0xdeadbeef);
1202 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1203 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1204 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1205 /* but they do allow final ones. */
1206 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1207 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1208 CryptMsgClose(msg);
1209 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1210 NULL, NULL);
1211 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1212 /* They also allow final updates with no data. */
1213 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1214 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1215 CryptMsgClose(msg);
1217 CryptDestroyKey(key);
1218 CryptReleaseContext(signer.hCryptProv, 0);
1219 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1220 CRYPT_DELETEKEYSET);
1223 static const BYTE signedEmptyBareContent[] = {
1224 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1225 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1226 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1227 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1228 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1229 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1230 static const BYTE signedEmptyContent[] = {
1231 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1232 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1233 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1234 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1235 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1236 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1237 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1238 static const BYTE detachedSignedBareContent[] = {
1239 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1240 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1241 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1242 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1243 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1244 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1245 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1246 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1247 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1248 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1249 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1250 static const BYTE detachedSignedContent[] = {
1251 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1252 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1253 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1254 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1255 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1256 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1257 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1258 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1259 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1260 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1261 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1262 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1263 static const BYTE signedBareContent[] = {
1264 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1265 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1266 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1267 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1268 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1269 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1270 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1271 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1272 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1273 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1274 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1275 static const BYTE signedContent[] = {
1276 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1277 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1278 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1279 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1280 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1281 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1282 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1283 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1284 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1285 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1286 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1287 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1288 0x0d };
1289 static const BYTE signedHash[] = {
1290 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1291 0x2f };
1292 static const BYTE signedEncodedSigner[] = {
1293 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1294 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1295 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1296 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1297 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1298 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1299 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1300 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1301 static const BYTE signedWithAuthAttrsBareContent[] = {
1302 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1303 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1304 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1305 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1306 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1307 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1308 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1309 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1310 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1311 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1312 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1313 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1314 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1315 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1316 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1317 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1318 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1319 0xff,0xc6,0x33,0x63,0x34 };
1320 static BYTE cert[] = {
1321 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1322 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1323 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1324 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1325 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1326 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1327 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1328 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1329 0xff,0x02,0x01,0x01 };
1330 static BYTE v1CertWithPubKey[] = {
1331 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1332 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1333 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1334 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1335 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1336 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1337 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1338 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1339 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1340 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1341 0x01,0x01 };
1342 static const BYTE signedWithCertEmptyBareContent[] = {
1343 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1344 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1345 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1346 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1347 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1348 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1349 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1350 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1351 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1352 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1353 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1354 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1355 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1356 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1357 static const BYTE signedWithCertBareContent[] = {
1358 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1359 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1360 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1361 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1362 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1363 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1364 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1365 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1366 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1367 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1368 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1369 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1370 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1371 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1372 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1373 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1374 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1375 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1376 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1377 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1378 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1379 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1380 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1381 0x30,0x30,0x30,0x30,0x5a };
1382 static const BYTE signedWithCrlEmptyBareContent[] = {
1383 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1384 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1385 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1386 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1387 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1388 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1389 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1390 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1391 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1392 static const BYTE signedWithCrlBareContent[] = {
1393 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1394 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1395 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1396 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1397 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1398 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1399 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1400 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1401 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1402 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1403 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1404 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1405 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1406 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1407 0xa8,0x0d };
1408 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1409 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1410 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1411 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1412 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1413 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1414 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1415 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1416 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1417 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1418 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1419 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1420 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1421 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1422 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1423 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1424 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1425 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1426 0x04,0x00 };
1427 static const BYTE signedWithCertAndCrlBareContent[] = {
1428 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1429 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1430 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1431 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1432 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1433 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1434 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1435 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1436 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1437 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1438 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1439 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1440 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1441 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1442 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1443 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1444 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1445 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1446 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1447 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1448 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1449 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1450 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1451 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1452 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1453 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1454 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1455 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1456 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1457 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1458 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1459 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1460 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1461 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1462 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1463 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1464 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1465 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1466 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1467 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1468 static BYTE v1CertWithValidPubKey[] = {
1469 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1470 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1471 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1472 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1473 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1474 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1475 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1476 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1477 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1478 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1479 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1480 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1481 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1482 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1483 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1484 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1485 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1486 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1487 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1488 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1489 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1490 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1491 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1492 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1493 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1494 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1495 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1496 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1497 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1498 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1499 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1500 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1501 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1502 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1503 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1504 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1505 0x00 };
1506 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1507 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1508 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1509 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1510 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1511 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1512 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1513 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1514 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1515 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1516 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1517 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1518 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1519 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1520 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1521 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1522 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1523 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1524 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1525 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1526 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1527 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1528 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1529 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1530 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1531 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1532 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1533 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1535 static void test_signed_msg_encoding(void)
1537 HCRYPTMSG msg;
1538 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1539 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1540 CERT_INFO certInfo = { 0 };
1541 CERT_BLOB encodedCert = { sizeof(cert), cert };
1542 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1543 char oid_common_name[] = szOID_COMMON_NAME;
1544 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1545 encodedCommonName };
1546 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1547 BOOL ret;
1548 HCRYPTKEY key;
1549 DWORD size;
1551 certInfo.SerialNumber.cbData = sizeof(serialNum);
1552 certInfo.SerialNumber.pbData = serialNum;
1553 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1554 certInfo.Issuer.pbData = encodedCommonName;
1555 signer.pCertInfo = &certInfo;
1556 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1557 signInfo.cSigners = 1;
1558 signInfo.rgSigners = &signer;
1559 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1560 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1561 if (!ret && GetLastError() == NTE_EXISTS)
1562 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1563 PROV_RSA_FULL, 0);
1564 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1565 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1566 0, 0, &key);
1567 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1569 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1570 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1571 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1573 check_param("detached signed empty bare content", msg,
1574 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1575 sizeof(signedEmptyBareContent));
1576 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1577 signedEmptyContent, sizeof(signedEmptyContent));
1578 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1579 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1580 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1581 signedHash, sizeof(signedHash));
1582 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1583 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1584 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1585 detachedSignedContent, sizeof(detachedSignedContent));
1586 SetLastError(0xdeadbeef);
1587 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1588 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1589 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1590 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1591 signedEncodedSigner, sizeof(signedEncodedSigner));
1593 CryptMsgClose(msg);
1595 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1596 NULL, NULL);
1597 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1599 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1600 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1601 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1602 signedEmptyContent, sizeof(signedEmptyContent));
1603 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1604 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1605 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1606 signedBareContent, sizeof(signedBareContent));
1607 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1608 signedContent, sizeof(signedContent));
1610 CryptMsgClose(msg);
1612 signer.cAuthAttr = 1;
1613 signer.rgAuthAttr = &attr;
1614 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1615 NULL, NULL);
1616 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1618 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1619 check_param("signed with auth attrs bare content", msg,
1620 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1621 sizeof(signedWithAuthAttrsBareContent));
1623 CryptMsgClose(msg);
1625 signer.cAuthAttr = 0;
1626 signInfo.rgCertEncoded = &encodedCert;
1627 signInfo.cCertEncoded = 1;
1628 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1629 NULL, NULL);
1630 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1632 check_param("signed with cert empty bare content", msg,
1633 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1634 sizeof(signedWithCertEmptyBareContent));
1635 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1636 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1637 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1638 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1640 CryptMsgClose(msg);
1642 signInfo.cCertEncoded = 0;
1643 signInfo.rgCrlEncoded = &encodedCrl;
1644 signInfo.cCrlEncoded = 1;
1645 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1646 NULL, NULL);
1647 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1649 check_param("signed with crl empty bare content", msg,
1650 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1651 sizeof(signedWithCrlEmptyBareContent));
1652 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1653 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1654 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1655 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1657 CryptMsgClose(msg);
1659 signInfo.cCertEncoded = 1;
1660 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1661 NULL, NULL);
1662 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1664 check_param("signed with cert and crl empty bare content", msg,
1665 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1666 sizeof(signedWithCertAndCrlEmptyBareContent));
1667 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1668 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1669 check_param("signed with cert and crl bare content", msg,
1670 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1671 sizeof(signedWithCertAndCrlBareContent));
1673 CryptMsgClose(msg);
1675 /* Test with a cert with a (bogus) public key */
1676 signInfo.cCrlEncoded = 0;
1677 encodedCert.cbData = sizeof(v1CertWithPubKey);
1678 encodedCert.pbData = v1CertWithPubKey;
1679 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1680 NULL, NULL);
1681 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1682 check_param("signedWithCertWithPubKeyBareContent", msg,
1683 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1684 sizeof(signedWithCertWithPubKeyBareContent));
1685 CryptMsgClose(msg);
1687 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1688 encodedCert.pbData = v1CertWithValidPubKey;
1689 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1690 NULL, NULL);
1691 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1692 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1693 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1694 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1695 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1696 check_param("signedWithCertWithValidPubKeyContent", msg,
1697 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1698 sizeof(signedWithCertWithValidPubKeyContent));
1699 CryptMsgClose(msg);
1701 CryptDestroyKey(key);
1702 CryptReleaseContext(signer.hCryptProv, 0);
1703 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1704 CRYPT_DELETEKEYSET);
1707 static void test_signed_msg_get_param(void)
1709 BOOL ret;
1710 HCRYPTMSG msg;
1711 DWORD size, value = 0;
1712 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1713 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1714 CERT_INFO certInfo = { 0 };
1716 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1717 NULL, NULL);
1718 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1720 /* Content and bare content are always gettable */
1721 size = 0;
1722 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1723 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1724 size = 0;
1725 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1726 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1727 /* For "signed" messages, so is the version. */
1728 size = 0;
1729 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1730 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1731 size = sizeof(value);
1732 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1733 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1734 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1735 /* But for this message, with no signers, the hash and signer aren't
1736 * available.
1738 size = 0;
1739 SetLastError(0xdeadbeef);
1740 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1741 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1742 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1743 SetLastError(0xdeadbeef);
1744 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1745 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1746 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1747 /* As usual, the type isn't available. */
1748 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1749 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1750 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1752 CryptMsgClose(msg);
1754 certInfo.SerialNumber.cbData = sizeof(serialNum);
1755 certInfo.SerialNumber.pbData = serialNum;
1756 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1757 certInfo.Issuer.pbData = encodedCommonName;
1758 signer.pCertInfo = &certInfo;
1759 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1760 signInfo.cSigners = 1;
1761 signInfo.rgSigners = &signer;
1762 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1763 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1764 if (!ret && GetLastError() == NTE_EXISTS)
1765 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1766 PROV_RSA_FULL, 0);
1767 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1768 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1769 NULL, NULL);
1770 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1772 /* This message, with one signer, has the hash and signer for index 0
1773 * available, but not for other indexes.
1775 size = 0;
1776 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1777 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1778 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1779 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1780 size = 0;
1781 SetLastError(0xdeadbeef);
1782 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1783 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1784 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1785 SetLastError(0xdeadbeef);
1786 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1787 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1788 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1789 /* As usual, the type isn't available. */
1790 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1791 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1792 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1794 CryptMsgClose(msg);
1796 CryptReleaseContext(signer.hCryptProv, 0);
1797 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1798 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1801 static void test_signed_msg(void)
1803 test_signed_msg_open();
1804 test_signed_msg_update();
1805 test_signed_msg_encoding();
1806 test_signed_msg_get_param();
1809 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1810 static const struct update_accum a4 = { 1, &b4 };
1812 static const BYTE bogusOIDContent[] = {
1813 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1814 0x04,0x00 };
1815 static const BYTE bogusHashContent[] = {
1816 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1817 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1818 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1819 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1820 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1822 static void test_decode_msg_update(void)
1824 HCRYPTMSG msg;
1825 BOOL ret;
1826 CMSG_STREAM_INFO streamInfo = { 0 };
1827 DWORD i;
1828 struct update_accum accum = { 0, NULL };
1830 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1831 /* Update with a full message in a final update */
1832 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1833 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1834 /* Can't update after a final update */
1835 SetLastError(0xdeadbeef);
1836 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1837 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1838 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1839 CryptMsgClose(msg);
1841 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1842 /* Can't send a non-final update without streaming */
1843 SetLastError(0xdeadbeef);
1844 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1845 FALSE);
1846 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1847 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1848 /* A subsequent final update succeeds */
1849 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1850 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1851 CryptMsgClose(msg);
1853 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1854 /* Updating a message that has a NULL stream callback fails */
1855 SetLastError(0xdeadbeef);
1856 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1857 FALSE);
1858 todo_wine
1859 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1860 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1861 /* Changing the callback pointer after the fact yields the same error (so
1862 * the message must copy the stream info, not just store a pointer to it)
1864 streamInfo.pfnStreamOutput = nop_stream_output;
1865 SetLastError(0xdeadbeef);
1866 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1867 FALSE);
1868 todo_wine
1869 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1870 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1871 CryptMsgClose(msg);
1873 /* Empty non-final updates are allowed when streaming.. */
1874 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1875 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1876 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1877 /* but final updates aren't when not enough data has been received. */
1878 SetLastError(0xdeadbeef);
1879 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1880 todo_wine
1881 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1882 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1883 CryptMsgClose(msg);
1885 /* Updating the message byte by byte is legal */
1886 streamInfo.pfnStreamOutput = accumulating_stream_output;
1887 streamInfo.pvArg = &accum;
1888 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1889 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1890 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1891 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1892 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1893 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1894 CryptMsgClose(msg);
1895 todo_wine
1896 check_updates("byte-by-byte empty content", &a4, &accum);
1897 free_updates(&accum);
1899 /* Decoding bogus content fails in non-streaming mode.. */
1900 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1901 SetLastError(0xdeadbeef);
1902 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1903 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1904 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1905 CryptMsgClose(msg);
1906 /* and as the final update in streaming mode.. */
1907 streamInfo.pfnStreamOutput = nop_stream_output;
1908 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1909 SetLastError(0xdeadbeef);
1910 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1911 todo_wine
1912 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1913 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1914 CryptMsgClose(msg);
1915 /* and even as a non-final update in streaming mode. */
1916 streamInfo.pfnStreamOutput = nop_stream_output;
1917 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1918 SetLastError(0xdeadbeef);
1919 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1920 todo_wine
1921 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1922 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1923 CryptMsgClose(msg);
1925 /* An empty message can be opened with indetermined type.. */
1926 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1927 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1928 TRUE);
1929 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1930 /* but decoding it as an explicitly typed message fails. */
1931 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1932 NULL);
1933 SetLastError(0xdeadbeef);
1934 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1935 TRUE);
1936 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1937 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1938 CryptMsgClose(msg);
1939 /* On the other hand, decoding the bare content of an empty message fails
1940 * with unspecified type..
1942 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1943 SetLastError(0xdeadbeef);
1944 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1945 sizeof(dataEmptyBareContent), TRUE);
1946 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1947 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1948 CryptMsgClose(msg);
1949 /* but succeeds with explicit type. */
1950 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1951 NULL);
1952 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1953 sizeof(dataEmptyBareContent), TRUE);
1954 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1955 CryptMsgClose(msg);
1957 /* Decoding valid content with an unsupported OID fails */
1958 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1959 SetLastError(0xdeadbeef);
1960 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
1961 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1962 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1963 CryptMsgClose(msg);
1965 /* Similarly, opening an empty hash with unspecified type succeeds.. */
1966 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1967 SetLastError(0xdeadbeef);
1968 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1969 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1970 CryptMsgClose(msg);
1971 /* while with specified type it fails. */
1972 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1973 NULL);
1974 SetLastError(0xdeadbeef);
1975 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1976 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1977 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1978 CryptMsgClose(msg);
1979 /* On the other hand, decoding the bare content of an empty hash message
1980 * fails with unspecified type..
1982 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1983 SetLastError(0xdeadbeef);
1984 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1985 sizeof(hashEmptyBareContent), TRUE);
1986 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1987 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1988 CryptMsgClose(msg);
1989 /* but succeeds with explicit type. */
1990 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1991 NULL);
1992 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1993 sizeof(hashEmptyBareContent), TRUE);
1994 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1995 CryptMsgClose(msg);
1997 /* And again, opening a (non-empty) hash message with unspecified type
1998 * succeeds..
2000 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2001 SetLastError(0xdeadbeef);
2002 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2003 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2004 CryptMsgClose(msg);
2005 /* while with specified type it fails.. */
2006 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2007 NULL);
2008 SetLastError(0xdeadbeef);
2009 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2010 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2011 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2012 CryptMsgClose(msg);
2013 /* and decoding the bare content of a non-empty hash message fails with
2014 * unspecified type..
2016 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2017 SetLastError(0xdeadbeef);
2018 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2019 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2020 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2021 CryptMsgClose(msg);
2022 /* but succeeds with explicit type. */
2023 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2024 NULL);
2025 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2026 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2027 CryptMsgClose(msg);
2029 /* Opening a (non-empty) hash message with unspecified type and a bogus
2030 * hash value succeeds..
2032 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2033 SetLastError(0xdeadbeef);
2034 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2035 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2036 CryptMsgClose(msg);
2038 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2039 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2040 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2041 CryptMsgClose(msg);
2042 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2043 SetLastError(0xdeadbeef);
2044 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2045 sizeof(signedWithCertAndCrlBareContent), TRUE);
2046 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2047 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2048 CryptMsgClose(msg);
2049 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2050 NULL);
2051 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2052 sizeof(signedWithCertAndCrlBareContent), TRUE);
2053 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2054 CryptMsgClose(msg);
2057 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2058 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2060 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2061 const CMSG_SIGNER_INFO *expected)
2063 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2064 expected->dwVersion, got->dwVersion);
2065 ok(got->Issuer.cbData == expected->Issuer.cbData,
2066 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2067 got->Issuer.cbData);
2068 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2069 "Unexpected issuer\n");
2070 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2071 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2072 got->SerialNumber.cbData);
2073 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2074 got->SerialNumber.cbData), "Unexpected serial number\n");
2075 /* FIXME: check more things */
2078 static const BYTE signedWithCertAndCrlComputedHash[] = {
2079 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2080 0x2f };
2082 static void test_decode_msg_get_param(void)
2084 HCRYPTMSG msg;
2085 BOOL ret;
2086 DWORD size = 0, value;
2087 LPBYTE buf;
2089 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2090 SetLastError(0xdeadbeef);
2091 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2092 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2093 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2094 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2095 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2096 sizeof(msgData));
2097 CryptMsgClose(msg);
2099 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2100 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2101 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2102 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2103 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2104 emptyHashParam, sizeof(emptyHashParam));
2105 CryptMsgClose(msg);
2106 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2107 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2108 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2109 sizeof(msgData));
2110 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2111 sizeof(hashParam));
2112 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2113 hashParam, sizeof(hashParam));
2114 /* Curiously, getting the hash of index 1 succeeds, even though there's
2115 * only one hash.
2117 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2118 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2119 buf = CryptMemAlloc(size);
2120 if (buf)
2122 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2123 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2124 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2125 CryptMemFree(buf);
2127 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2128 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2129 value = CMSG_HASHED_DATA_V0;
2130 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2131 sizeof(value));
2132 CryptMsgClose(msg);
2134 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2135 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2136 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2137 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2138 sizeof(msgData));
2139 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2140 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2141 size = sizeof(value);
2142 value = 2112;
2143 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2144 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2145 ok(value == 1, "Expected 1 signer, got %d\n", value);
2146 size = 0;
2147 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2148 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2149 if (ret)
2150 buf = CryptMemAlloc(size);
2151 else
2152 buf = NULL;
2153 if (buf)
2155 CMSG_SIGNER_INFO signer = { 0 };
2157 signer.dwVersion = 1;
2158 signer.Issuer.cbData = sizeof(encodedCommonName);
2159 signer.Issuer.pbData = encodedCommonName;
2160 signer.SerialNumber.cbData = sizeof(serialNum);
2161 signer.SerialNumber.pbData = serialNum;
2162 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2163 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2164 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2165 CryptMemFree(buf);
2167 /* index is ignored when getting signer count */
2168 size = sizeof(value);
2169 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2170 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2171 ok(value == 1, "Expected 1 signer, got %d\n", value);
2172 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2173 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2174 ok(value == 0, "Expected 0 certs, got %d\n", value);
2175 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2176 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2177 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2178 CryptMsgClose(msg);
2179 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2180 NULL);
2181 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2182 sizeof(signedWithCertAndCrlBareContent), TRUE);
2183 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2184 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2185 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2186 ok(value == 1, "Expected 1 cert, got %d\n", value);
2187 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2188 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2189 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2190 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2191 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2192 check_param("signed with cert and CRL computed hash", msg,
2193 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2194 sizeof(signedWithCertAndCrlComputedHash));
2195 CryptMsgClose(msg);
2198 static void test_decode_msg(void)
2200 test_decode_msg_update();
2201 test_decode_msg_get_param();
2204 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2205 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2206 static BYTE encodedPubKey[] = {
2207 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2208 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2209 0x0d,0x0e,0x0f };
2210 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2211 static BYTE mod_encoded[] = {
2212 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2213 0x01,0x00,0x01 };
2215 static void test_msg_control(void)
2217 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2218 BOOL ret;
2219 HCRYPTMSG msg;
2220 DWORD i;
2221 CERT_INFO certInfo = { 0 };
2222 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2223 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2224 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2226 /* Crashes
2227 ret = CryptMsgControl(NULL, 0, 0, NULL);
2230 /* Data encode messages don't allow any sort of control.. */
2231 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2232 NULL);
2233 /* either with no prior update.. */
2234 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2236 SetLastError(0xdeadbeef);
2237 ret = CryptMsgControl(msg, 0, i, NULL);
2238 ok(!ret && GetLastError() == E_INVALIDARG,
2239 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2241 /* or after an update. */
2242 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2244 SetLastError(0xdeadbeef);
2245 ret = CryptMsgControl(msg, 0, i, NULL);
2246 ok(!ret && GetLastError() == E_INVALIDARG,
2247 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2249 CryptMsgClose(msg);
2251 /* Hash encode messages don't allow any sort of control.. */
2252 hashInfo.cbSize = sizeof(hashInfo);
2253 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2254 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2255 NULL, NULL);
2256 /* either with no prior update.. */
2257 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2259 SetLastError(0xdeadbeef);
2260 ret = CryptMsgControl(msg, 0, i, NULL);
2261 ok(!ret && GetLastError() == E_INVALIDARG,
2262 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2264 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2265 /* or after an update. */
2266 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2268 SetLastError(0xdeadbeef);
2269 ret = CryptMsgControl(msg, 0, i, NULL);
2270 ok(!ret && GetLastError() == E_INVALIDARG,
2271 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2273 CryptMsgClose(msg);
2275 /* Signed encode messages likewise don't allow any sort of control.. */
2276 signInfo.cbSize = sizeof(signInfo);
2277 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2278 NULL, NULL);
2279 /* either before an update.. */
2280 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2282 SetLastError(0xdeadbeef);
2283 ret = CryptMsgControl(msg, 0, i, NULL);
2284 ok(!ret && GetLastError() == E_INVALIDARG,
2285 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2287 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2288 /* or after an update. */
2289 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2291 SetLastError(0xdeadbeef);
2292 ret = CryptMsgControl(msg, 0, i, NULL);
2293 ok(!ret && GetLastError() == E_INVALIDARG,
2294 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2296 CryptMsgClose(msg);
2298 /* Decode messages behave a bit differently. */
2299 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2300 /* Bad control type */
2301 SetLastError(0xdeadbeef);
2302 ret = CryptMsgControl(msg, 0, 0, NULL);
2303 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2304 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2305 SetLastError(0xdeadbeef);
2306 ret = CryptMsgControl(msg, 1, 0, NULL);
2307 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2308 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2309 /* Can't verify the hash of an indeterminate-type message */
2310 SetLastError(0xdeadbeef);
2311 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2312 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2313 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2314 /* Crashes
2315 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2317 /* Can't decrypt an indeterminate-type message */
2318 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2319 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2320 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2321 CryptMsgClose(msg);
2323 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2324 NULL);
2325 /* Can't verify the hash of an empty message */
2326 SetLastError(0xdeadbeef);
2327 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2328 todo_wine
2329 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2330 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2331 /* Crashes
2332 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2334 /* Can't verify the signature of a hash message */
2335 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2336 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2337 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2338 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2339 TRUE);
2340 /* Oddly enough, this fails */
2341 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2342 todo_wine
2343 ok(!ret, "Expected failure\n");
2344 CryptMsgClose(msg);
2345 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2346 NULL);
2347 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2348 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2349 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2350 /* Can't decrypt an indeterminate-type message */
2351 SetLastError(0xdeadbeef);
2352 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2353 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2354 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2355 CryptMsgClose(msg);
2357 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2358 NULL);
2359 /* Can't verify the hash of a signed message */
2360 SetLastError(0xdeadbeef);
2361 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2362 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2363 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2364 /* Can't decrypt a signed message */
2365 SetLastError(0xdeadbeef);
2366 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2367 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2368 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2369 /* Crash
2370 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2371 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2373 CryptMsgUpdate(msg, signedWithCertBareContent,
2374 sizeof(signedWithCertBareContent), TRUE);
2375 /* With an empty cert info, the signer can't be found in the message (and
2376 * the signature can't be verified.
2378 SetLastError(0xdeadbeef);
2379 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2380 ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2381 "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2382 /* The cert info is expected to have an issuer, serial number, and public
2383 * key info set.
2385 certInfo.SerialNumber.cbData = sizeof(serialNum);
2386 certInfo.SerialNumber.pbData = serialNum;
2387 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2388 certInfo.Issuer.pbData = encodedCommonName;
2389 SetLastError(0xdeadbeef);
2390 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2391 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2392 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2393 CryptMsgClose(msg);
2394 /* This cert has a public key, but it's not in a usable form */
2395 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2396 NULL);
2397 CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2398 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2399 /* Again, cert info needs to have a public key set */
2400 SetLastError(0xdeadbeef);
2401 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2402 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2403 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2404 /* The public key is supposed to be in encoded form.. */
2405 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2406 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2407 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2408 SetLastError(0xdeadbeef);
2409 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2410 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2411 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2412 /* but not as a X509_PUBLIC_KEY_INFO.. */
2413 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2414 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2415 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2416 SetLastError(0xdeadbeef);
2417 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2418 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2419 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2420 /* This decodes successfully, but it doesn't match any key in the message */
2421 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2422 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2423 SetLastError(0xdeadbeef);
2424 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2425 /* In Wine's rsaenh, this fails to decode because the key length is too
2426 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
2427 * now.
2429 todo_wine
2430 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2431 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2432 CryptMsgClose(msg);
2433 /* A message with no data doesn't have a valid signature */
2434 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2435 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2436 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2437 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2438 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2439 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2440 SetLastError(0xdeadbeef);
2441 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2442 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2443 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2444 CryptMsgClose(msg);
2445 /* Finally, this succeeds */
2446 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2447 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2448 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2449 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2450 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2453 static void test_msg_get_signer_count(void)
2455 LONG count;
2457 SetLastError(0xdeadbeef);
2458 count = CryptGetMessageSignerCount(0, NULL, 0);
2459 ok(count == -1, "Expected -1, got %d\n", count);
2460 ok(GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n",
2461 GetLastError());
2462 SetLastError(0xdeadbeef);
2463 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, NULL, 0);
2464 ok(count == -1, "Expected -1, got %d\n", count);
2465 ok(GetLastError() == CRYPT_E_ASN1_EOD,
2466 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2467 SetLastError(0xdeadbeef);
2468 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2469 dataEmptyBareContent, sizeof(dataEmptyBareContent));
2470 ok(count == -1, "Expected -1, got %d\n", count);
2471 ok(GetLastError() == CRYPT_E_ASN1_BADTAG,
2472 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2473 SetLastError(0xdeadbeef);
2474 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2475 dataEmptyContent, sizeof(dataEmptyContent));
2476 ok(count == -1, "Expected -1, got %d\n", count);
2477 ok(GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2478 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2479 SetLastError(0xdeadbeef);
2480 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2481 signedEmptyBareContent, sizeof(signedEmptyBareContent));
2482 ok(count == -1, "Expected -1, got %d\n", count);
2483 ok(GetLastError() == CRYPT_E_ASN1_BADTAG,
2484 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2485 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2486 signedEmptyContent, sizeof(signedEmptyContent));
2487 ok(count == 1, "Expected 1, got %d\n", count);
2490 static const BYTE signedWithCertEmptyContent[] = {
2491 0x30,0x81,0xdf,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
2492 0x81,0xd1,0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
2493 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,
2494 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2495 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2496 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2497 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2498 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2499 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2500 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
2501 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2502 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
2503 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
2504 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
2505 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
2506 0x00 };
2507 static const BYTE signedWithCertContent[] = {
2508 0x30,0x82,0x01,0x32,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
2509 0xa0,0x82,0x01,0x23,0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
2510 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
2511 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
2512 0x02,0x03,0x04,0xa0,0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
2513 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
2514 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
2515 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
2516 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
2517 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
2518 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
2519 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
2520 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,
2521 0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,
2522 0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,
2523 0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,
2524 0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,
2525 0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,
2526 0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,
2527 0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,
2528 0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
2529 static const BYTE signedWithCertWithPubKeyContent[] = {
2530 0x30,0x81,0xfc,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
2531 0x81,0xee,0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
2532 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,
2533 0x98,0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,
2534 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
2535 0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2536 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
2537 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,
2538 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2539 0x6e,0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2540 0x01,0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
2541 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,
2542 0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,
2543 0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
2544 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2545 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
2546 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
2548 static void test_verify_message_signature(void)
2550 BOOL ret;
2551 CRYPT_VERIFY_MESSAGE_PARA para = { 0 };
2552 PCCERT_CONTEXT cert;
2553 DWORD cbDecoded;
2555 SetLastError(0xdeadbeef);
2556 ret = CryptVerifyMessageSignature(NULL, 0, NULL, 0, NULL, 0, NULL);
2557 ok(!ret && GetLastError() == E_INVALIDARG,
2558 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2559 SetLastError(0xdeadbeef);
2560 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2561 ok(!ret && GetLastError() == E_INVALIDARG,
2562 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2563 para.cbSize = sizeof(para);
2564 SetLastError(0xdeadbeef);
2565 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2566 ok(!ret && GetLastError() == E_INVALIDARG,
2567 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2568 para.cbSize = 0;
2569 para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING;
2570 SetLastError(0xdeadbeef);
2571 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2572 ok(!ret && GetLastError() == E_INVALIDARG,
2573 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2574 para.cbSize = sizeof(para);
2575 SetLastError(0xdeadbeef);
2576 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2577 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2578 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2579 /* Check whether cert is set on error */
2580 cert = (PCCERT_CONTEXT)0xdeadbeef;
2581 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, &cert);
2582 ok(cert == NULL, "Expected NULL cert\n");
2583 /* Check whether cbDecoded is set on error */
2584 cbDecoded = 0xdeadbeef;
2585 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, &cbDecoded,
2586 NULL);
2587 ok(!cbDecoded, "Expected 0\n");
2588 SetLastError(0xdeadbeef);
2589 ret = CryptVerifyMessageSignature(&para, 0, dataEmptyBareContent,
2590 sizeof(dataEmptyBareContent), NULL, 0, NULL);
2591 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2592 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2593 SetLastError(0xdeadbeef);
2594 ret = CryptVerifyMessageSignature(&para, 0, dataEmptyContent,
2595 sizeof(dataEmptyContent), NULL, 0, NULL);
2596 ok(!ret && GetLastError() == CRYPT_E_UNEXPECTED_MSG_TYPE,
2597 "Expected CRYPT_E_UNEXPECTED_MSG_TYPE, got %08x\n", GetLastError());
2598 SetLastError(0xdeadbeef);
2599 ret = CryptVerifyMessageSignature(&para, 0, signedEmptyBareContent,
2600 sizeof(signedEmptyBareContent), NULL, 0, NULL);
2601 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2602 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2603 SetLastError(0xdeadbeef);
2604 ret = CryptVerifyMessageSignature(&para, 0, signedEmptyContent,
2605 sizeof(signedEmptyContent), NULL, 0, NULL);
2606 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2607 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2608 SetLastError(0xdeadbeef);
2609 ret = CryptVerifyMessageSignature(&para, 0, signedContent,
2610 sizeof(signedContent), NULL, 0, NULL);
2611 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2612 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2613 /* FIXME: Windows fails with CRYPT_E_NOT_FOUND for these messages, but
2614 * their signer certs have invalid public keys that fail to decode. In
2615 * Wine therefore the failure is an ASN error. Need some messages with
2616 * valid public keys and invalid signatures to check against.
2618 ret = CryptVerifyMessageSignature(&para, 0, signedWithCertEmptyContent,
2619 sizeof(signedWithCertEmptyContent), NULL, 0, NULL);
2620 ok(!ret, "Expected failure\n");
2621 ret = CryptVerifyMessageSignature(&para, 0, signedWithCertContent,
2622 sizeof(signedWithCertContent), NULL, 0, NULL);
2623 ok(!ret, "Expected failure\n");
2624 ret = CryptVerifyMessageSignature(&para, 0, signedWithCertWithPubKeyContent,
2625 sizeof(signedWithCertWithPubKeyContent), NULL, 0, NULL);
2626 ok(!ret, "Expected failure\n");
2629 START_TEST(msg)
2631 init_function_pointers();
2633 /* Basic parameter checking tests */
2634 test_msg_open_to_encode();
2635 test_msg_open_to_decode();
2636 test_msg_get_param();
2637 test_msg_close();
2638 test_msg_control();
2640 /* Message-type specific tests */
2641 test_data_msg();
2642 test_hash_msg();
2643 test_signed_msg();
2644 test_decode_msg();
2646 /* simplified message functions */
2647 test_msg_get_signer_count();
2648 test_verify_message_signature();