Assorted spelling fixes.
[wine/testsucceed.git] / dlls / crypt32 / tests / msg.c
blobab35b3a19e582c7e9baa3c1f29ae1f1763c29a6f
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 check_updates("data message with indefinite length", &a3, &accum);
663 free_updates(&accum);
666 static void test_data_msg(void)
668 test_data_msg_open();
669 test_data_msg_update();
670 test_data_msg_get_param();
671 test_data_msg_encoding();
674 static void test_hash_msg_open(void)
676 HCRYPTMSG msg;
677 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
678 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
680 SetLastError(0xdeadbeef);
681 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
682 NULL, NULL);
683 ok(!msg && GetLastError() == E_INVALIDARG,
684 "Expected E_INVALIDARG, got %x\n", GetLastError());
685 hashInfo.cbSize = sizeof(hashInfo);
686 SetLastError(0xdeadbeef);
687 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
688 NULL, NULL);
689 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
690 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
691 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
692 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
693 NULL, NULL);
694 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
695 CryptMsgClose(msg);
696 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
697 CMSG_HASHED, &hashInfo, NULL, NULL);
698 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
699 CryptMsgClose(msg);
700 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
701 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
702 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
703 CryptMsgClose(msg);
706 static void test_hash_msg_update(void)
708 HCRYPTMSG msg;
709 BOOL ret;
710 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
711 { oid_rsa_md5, { 0, NULL } }, NULL };
712 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
714 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
715 CMSG_HASHED, &hashInfo, NULL, NULL);
716 /* Detached hashed messages opened in non-streaming mode allow non-final
717 * updates..
719 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
720 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
721 /* including non-final updates with no data.. */
722 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
723 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
724 /* and final updates with no data. */
725 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
726 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
727 /* But no updates are allowed after the final update. */
728 SetLastError(0xdeadbeef);
729 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
730 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
731 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
732 SetLastError(0xdeadbeef);
733 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
734 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
735 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
736 CryptMsgClose(msg);
737 /* Non-detached messages, in contrast, don't allow non-final updates in
738 * non-streaming mode.
740 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
741 NULL, NULL);
742 SetLastError(0xdeadbeef);
743 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
744 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
745 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
746 /* Final updates (including empty ones) are allowed. */
747 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
748 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
749 CryptMsgClose(msg);
750 /* And, of course, streaming mode allows non-final updates */
751 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
752 NULL, &streamInfo);
753 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
754 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
755 CryptMsgClose(msg);
756 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
757 * to be a bug, it isn't actually used - see encoding tests.)
759 streamInfo.pfnStreamOutput = NULL;
760 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
761 NULL, &streamInfo);
762 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
763 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
764 CryptMsgClose(msg);
767 static const BYTE emptyHashParam[] = {
768 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
769 0x7e };
771 static void test_hash_msg_get_param(void)
773 HCRYPTMSG msg;
774 BOOL ret;
775 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
776 { oid_rsa_md5, { 0, NULL } }, NULL };
777 DWORD size, value;
778 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
779 BYTE buf[16];
781 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
782 NULL, NULL);
783 /* Content and bare content are always gettable for non-streamed messages */
784 size = 0;
785 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
786 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
787 size = 0;
788 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
789 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
790 /* For an encoded hash message, the hash data aren't available */
791 SetLastError(0xdeadbeef);
792 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
793 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
794 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
795 /* The hash is also available. */
796 size = 0;
797 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
798 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
799 ok(size == sizeof(buf), "Unexpected size %d\n", size);
800 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
801 if (size == sizeof(buf))
802 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
803 /* By getting the hash, further updates are not allowed */
804 SetLastError(0xdeadbeef);
805 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
806 ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
807 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
808 /* Even after a final update, the hash data aren't available */
809 SetLastError(0xdeadbeef);
810 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
811 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
812 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
813 /* The version is also available, and should be zero for this message. */
814 size = 0;
815 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
816 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
817 size = sizeof(value);
818 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
819 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
820 ok(value == 0, "Expected version 0, got %d\n", value);
821 /* As usual, the type isn't available. */
822 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
823 ok(!ret, "Expected failure\n");
824 CryptMsgClose(msg);
826 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
827 NULL, &streamInfo);
828 /* Streamed messages don't allow you to get the content or bare content. */
829 SetLastError(0xdeadbeef);
830 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
831 ok(!ret && GetLastError() == E_INVALIDARG,
832 "Expected E_INVALIDARG, got %x\n", GetLastError());
833 SetLastError(0xdeadbeef);
834 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
835 ok(!ret && GetLastError() == E_INVALIDARG,
836 "Expected E_INVALIDARG, got %x\n", GetLastError());
837 /* The hash is still available. */
838 size = 0;
839 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
840 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
841 ok(size == sizeof(buf), "Unexpected size %d\n", size);
842 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
843 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
844 if (size == sizeof(buf))
845 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
846 /* After updating the hash, further updates aren't allowed on streamed
847 * messages either.
849 SetLastError(0xdeadbeef);
850 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
851 ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
852 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
853 CryptMsgClose(msg);
856 static const BYTE hashEmptyBareContent[] = {
857 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
858 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
859 static const BYTE hashEmptyContent[] = {
860 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
861 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
862 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
863 static const BYTE hashBareContent[] = {
864 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
865 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
866 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
867 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
868 static const BYTE hashContent[] = {
869 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
870 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
871 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
872 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
873 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
875 static const BYTE detachedHashNonFinalBareContent[] = {
876 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
877 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
878 0x07,0x01,0x04,0x00 };
879 static const BYTE detachedHashNonFinalContent[] = {
880 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
881 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
882 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
883 0x07,0x01,0x04,0x00 };
884 static const BYTE detachedHashBareContent[] = {
885 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
886 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
887 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
888 0x9d,0x2a,0x8f,0x26,0x2f };
889 static const BYTE detachedHashContent[] = {
890 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
891 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
892 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
893 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
894 0x9d,0x2a,0x8f,0x26,0x2f };
896 static void test_hash_msg_encoding(void)
898 HCRYPTMSG msg;
899 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
900 BOOL ret;
901 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
902 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
904 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
905 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
906 NULL, NULL);
907 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
908 hashEmptyBareContent, sizeof(hashEmptyBareContent));
909 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
910 hashEmptyContent, sizeof(hashEmptyContent));
911 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
912 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
913 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
914 hashBareContent, sizeof(hashBareContent));
915 check_param("hash content", msg, CMSG_CONTENT_PARAM,
916 hashContent, sizeof(hashContent));
917 CryptMsgClose(msg);
918 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
919 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
920 CMSG_HASHED, &hashInfo, NULL, NULL);
921 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
922 hashEmptyBareContent, sizeof(hashEmptyBareContent));
923 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
924 hashEmptyContent, sizeof(hashEmptyContent));
925 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
926 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
927 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
928 hashBareContent, sizeof(hashBareContent));
929 check_param("hash content", msg, CMSG_CONTENT_PARAM,
930 hashContent, sizeof(hashContent));
931 CryptMsgClose(msg);
932 /* Same test, but with CMSG_DETACHED_FLAG set */
933 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
934 CMSG_HASHED, &hashInfo, NULL, NULL);
935 check_param("detached hash empty bare content", msg,
936 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
937 sizeof(hashEmptyBareContent));
938 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
939 hashEmptyContent, sizeof(hashEmptyContent));
940 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
941 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
942 check_param("detached hash not final bare content", msg,
943 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
944 sizeof(detachedHashNonFinalBareContent));
945 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
946 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
947 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
948 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
949 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
950 detachedHashBareContent, sizeof(detachedHashBareContent));
951 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
952 detachedHashContent, sizeof(detachedHashContent));
953 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
954 detachedHashBareContent, sizeof(detachedHashBareContent));
955 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
956 detachedHashContent, sizeof(detachedHashContent));
957 CryptMsgClose(msg);
958 /* In what appears to be a bug, streamed updates to hash messages don't
959 * call the output function.
961 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
962 NULL, &streamInfo);
963 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
964 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
965 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
966 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
967 CryptMsgClose(msg);
968 check_updates("empty hash message", &empty_accum, &accum);
969 free_updates(&accum);
971 streamInfo.cbContent = sizeof(msgData);
972 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
973 NULL, &streamInfo);
974 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
975 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
976 CryptMsgClose(msg);
977 check_updates("hash message", &empty_accum, &accum);
978 free_updates(&accum);
980 streamInfo.cbContent = sizeof(msgData);
981 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
982 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
983 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
984 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
985 CryptMsgClose(msg);
986 check_updates("detached hash message", &empty_accum, &accum);
987 free_updates(&accum);
990 static void test_hash_msg(void)
992 test_hash_msg_open();
993 test_hash_msg_update();
994 test_hash_msg_get_param();
995 test_hash_msg_encoding();
998 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
999 'm','p',0 };
1000 static BYTE serialNum[] = { 1 };
1001 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1002 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1004 static void test_signed_msg_open(void)
1006 HCRYPTMSG msg;
1007 BOOL ret;
1008 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1009 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1010 CERT_INFO certInfo = { 0 };
1012 SetLastError(0xdeadbeef);
1013 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1014 NULL, NULL);
1015 ok(!msg && GetLastError() == E_INVALIDARG,
1016 "Expected E_INVALIDARG, got %x\n", GetLastError());
1017 signInfo.cbSize = sizeof(signInfo);
1018 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1019 NULL, NULL);
1020 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1021 CryptMsgClose(msg);
1023 signInfo.cSigners = 1;
1024 signInfo.rgSigners = &signer;
1025 /* With signer.pCertInfo unset, attempting to open this message this
1026 * crashes.
1028 signer.pCertInfo = &certInfo;
1029 /* The cert info must contain a serial number and an issuer. */
1030 SetLastError(0xdeadbeef);
1031 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1032 NULL, NULL);
1033 ok(!msg && GetLastError() == E_INVALIDARG,
1034 "Expected E_INVALIDARG, got %x\n", GetLastError());
1035 certInfo.SerialNumber.cbData = sizeof(serialNum);
1036 certInfo.SerialNumber.pbData = serialNum;
1037 SetLastError(0xdeadbeef);
1038 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1039 NULL, NULL);
1040 ok(!msg && GetLastError() == E_INVALIDARG,
1041 "Expected E_INVALIDARG, got %x\n", GetLastError());
1042 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1043 certInfo.Issuer.pbData = encodedCommonName;
1044 SetLastError(0xdeadbeef);
1045 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1046 NULL, NULL);
1047 ok(!msg && GetLastError() == E_INVALIDARG,
1048 "Expected E_INVALIDARG, got %x\n", GetLastError());
1050 /* The signer's hCryptProv must be set to something. Whether it's usable
1051 * or not will be checked after the hash algorithm is checked (see next
1052 * test.)
1054 signer.hCryptProv = 1;
1055 SetLastError(0xdeadbeef);
1056 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1057 NULL, NULL);
1058 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1059 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1060 /* The signer's hash algorithm must also be set. */
1061 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1062 SetLastError(0xdeadbeef);
1063 /* Crashes in advapi32 in wine, don't do it */
1064 if (0) {
1065 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1066 &signInfo, NULL, NULL);
1067 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1068 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1070 /* The signer's hCryptProv must also be valid. */
1071 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1072 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1073 if (!ret && GetLastError() == NTE_EXISTS)
1074 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1075 PROV_RSA_FULL, 0);
1076 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1077 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1078 NULL, NULL);
1079 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1080 CryptMsgClose(msg);
1082 CryptReleaseContext(signer.hCryptProv, 0);
1083 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1084 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1087 static const BYTE privKey[] = {
1088 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1089 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1090 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1091 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1092 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1093 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1094 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1095 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1096 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1097 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1098 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1099 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1100 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1101 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1102 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1103 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1104 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1105 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1106 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1107 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1108 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1109 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1110 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1111 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1112 static BYTE pubKey[] = {
1113 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1114 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1115 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1116 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1117 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1119 static void test_signed_msg_update(void)
1121 HCRYPTMSG msg;
1122 BOOL ret;
1123 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1124 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1125 CERT_INFO certInfo = { 0 };
1126 HCRYPTKEY key;
1128 certInfo.SerialNumber.cbData = sizeof(serialNum);
1129 certInfo.SerialNumber.pbData = serialNum;
1130 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1131 certInfo.Issuer.pbData = encodedCommonName;
1132 signer.pCertInfo = &certInfo;
1133 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1134 signInfo.cSigners = 1;
1135 signInfo.rgSigners = &signer;
1136 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1137 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1138 if (!ret && GetLastError() == NTE_EXISTS)
1139 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1140 PROV_RSA_FULL, 0);
1141 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1142 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1143 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1144 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1145 /* Detached CMSG_SIGNED allows non-final updates. */
1146 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1147 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1148 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1149 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1150 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1151 /* The final update requires a private key in the hCryptProv, in order to
1152 * generate the signature.
1154 SetLastError(0xdeadbeef);
1155 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1156 ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1157 GetLastError() == NTE_NO_KEY),
1158 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1159 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1160 0, 0, &key);
1161 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1162 /* The final update should be able to succeed now that a key exists, but
1163 * the previous (invalid) final update prevents it.
1165 SetLastError(0xdeadbeef);
1166 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1167 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1168 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1169 CryptMsgClose(msg);
1171 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1172 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1173 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1174 /* Detached CMSG_SIGNED allows non-final updates. */
1175 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1176 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1177 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1178 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1179 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1180 /* Now that the private key exists, the final update can succeed (even
1181 * with no data.)
1183 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1184 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1185 /* But no updates are allowed after the final update. */
1186 SetLastError(0xdeadbeef);
1187 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1188 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1189 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1190 SetLastError(0xdeadbeef);
1191 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1192 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1193 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1194 CryptMsgClose(msg);
1196 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1197 NULL, NULL);
1198 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1199 /* Non-detached messages don't allow non-final updates.. */
1200 SetLastError(0xdeadbeef);
1201 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1202 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1203 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1204 /* but they do allow final ones. */
1205 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1206 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1207 CryptMsgClose(msg);
1208 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1209 NULL, NULL);
1210 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1211 /* They also allow final updates with no data. */
1212 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1213 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1214 CryptMsgClose(msg);
1216 CryptDestroyKey(key);
1217 CryptReleaseContext(signer.hCryptProv, 0);
1218 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1219 CRYPT_DELETEKEYSET);
1222 static const BYTE signedEmptyBareContent[] = {
1223 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1224 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1225 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1226 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1227 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1228 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1229 static const BYTE signedEmptyContent[] = {
1230 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1231 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1232 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1233 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1234 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1235 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1236 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1237 static const BYTE detachedSignedBareContent[] = {
1238 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1239 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1240 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1241 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1242 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1243 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1244 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1245 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1246 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1247 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1248 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1249 static const BYTE detachedSignedContent[] = {
1250 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1251 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1252 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1253 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1254 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1255 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1256 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1257 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1258 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1259 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1260 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1261 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1262 static const BYTE signedBareContent[] = {
1263 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1264 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1265 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1266 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1267 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1268 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1269 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1270 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1271 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1272 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1273 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1274 static const BYTE signedContent[] = {
1275 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1276 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1277 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1278 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1279 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1280 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1281 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1282 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1283 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1284 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1285 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1286 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1287 0x0d };
1288 static const BYTE signedHash[] = {
1289 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1290 0x2f };
1291 static const BYTE signedEncodedSigner[] = {
1292 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1293 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1294 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1295 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1296 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1297 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1298 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1299 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1300 static const BYTE signedWithAuthAttrsBareContent[] = {
1301 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1302 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1303 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1304 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1305 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1306 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1307 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1308 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1309 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1310 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1311 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1312 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1313 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1314 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1315 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1316 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1317 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1318 0xff,0xc6,0x33,0x63,0x34 };
1319 static BYTE cert[] = {
1320 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1321 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1322 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1323 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1324 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1325 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1326 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1327 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1328 0xff,0x02,0x01,0x01 };
1329 static BYTE v1CertWithPubKey[] = {
1330 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1331 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1332 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1333 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1334 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1335 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1336 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1337 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1338 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1339 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1340 0x01,0x01 };
1341 static const BYTE signedWithCertEmptyBareContent[] = {
1342 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1343 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1344 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1345 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1346 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1347 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1348 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1349 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1350 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1351 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1352 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1353 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1354 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1355 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1356 static const BYTE signedWithCertBareContent[] = {
1357 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1358 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1359 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1360 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1361 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1362 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1363 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1364 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1365 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1366 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1367 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1368 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1369 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1370 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1371 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1372 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1373 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1374 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1375 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1376 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1377 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1378 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1379 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1380 0x30,0x30,0x30,0x30,0x5a };
1381 static const BYTE signedWithCrlEmptyBareContent[] = {
1382 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1383 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1384 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1385 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1386 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1387 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1388 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1389 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1390 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1391 static const BYTE signedWithCrlBareContent[] = {
1392 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1393 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1394 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1395 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1396 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1397 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1398 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1399 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1400 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1401 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1402 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1403 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1404 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1405 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1406 0xa8,0x0d };
1407 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1408 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1409 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1410 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1411 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1412 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1413 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1414 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1415 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1416 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1417 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1418 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1419 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1420 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1421 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1422 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1423 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1424 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1425 0x04,0x00 };
1426 static const BYTE signedWithCertAndCrlBareContent[] = {
1427 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1428 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1429 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1430 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1431 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1432 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1433 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1434 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1435 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1436 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1437 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1438 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1439 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1440 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1441 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1442 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1443 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1444 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1445 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1446 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1447 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1448 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1449 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1450 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1451 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1452 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1453 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1454 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1455 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1456 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1457 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1458 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1459 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1460 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1461 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1462 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1463 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1464 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1465 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1466 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1467 static BYTE v1CertWithValidPubKey[] = {
1468 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1469 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1470 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1471 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1472 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1473 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1474 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1475 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1476 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1477 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1478 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1479 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1480 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1481 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1482 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1483 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1484 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1485 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1486 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1487 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1488 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1489 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1490 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1491 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1492 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1493 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1494 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1495 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1496 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1497 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1498 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1499 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1500 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1501 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1502 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1503 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1504 0x00 };
1505 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1506 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1507 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1508 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1509 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1510 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1511 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1512 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1513 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1514 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1515 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1516 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1517 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1518 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1519 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1520 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1521 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1522 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1523 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1524 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1525 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1526 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1527 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1528 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1529 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1530 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1531 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1532 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1534 static void test_signed_msg_encoding(void)
1536 HCRYPTMSG msg;
1537 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1538 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1539 CERT_INFO certInfo = { 0 };
1540 CERT_BLOB encodedCert = { sizeof(cert), cert };
1541 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1542 char oid_common_name[] = szOID_COMMON_NAME;
1543 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1544 encodedCommonName };
1545 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1546 BOOL ret;
1547 HCRYPTKEY key;
1548 DWORD size;
1550 certInfo.SerialNumber.cbData = sizeof(serialNum);
1551 certInfo.SerialNumber.pbData = serialNum;
1552 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1553 certInfo.Issuer.pbData = encodedCommonName;
1554 signer.pCertInfo = &certInfo;
1555 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1556 signInfo.cSigners = 1;
1557 signInfo.rgSigners = &signer;
1558 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1559 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1560 if (!ret && GetLastError() == NTE_EXISTS)
1561 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1562 PROV_RSA_FULL, 0);
1563 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1564 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1565 0, 0, &key);
1566 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1568 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1569 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1570 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1572 check_param("detached signed empty bare content", msg,
1573 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1574 sizeof(signedEmptyBareContent));
1575 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1576 signedEmptyContent, sizeof(signedEmptyContent));
1577 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1578 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1579 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1580 signedHash, sizeof(signedHash));
1581 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1582 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1583 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1584 detachedSignedContent, sizeof(detachedSignedContent));
1585 SetLastError(0xdeadbeef);
1586 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1587 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1588 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1589 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1590 signedEncodedSigner, sizeof(signedEncodedSigner));
1592 CryptMsgClose(msg);
1594 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1595 NULL, NULL);
1596 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1598 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1599 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1600 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1601 signedEmptyContent, sizeof(signedEmptyContent));
1602 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1603 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1604 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1605 signedBareContent, sizeof(signedBareContent));
1606 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1607 signedContent, sizeof(signedContent));
1609 CryptMsgClose(msg);
1611 signer.cAuthAttr = 1;
1612 signer.rgAuthAttr = &attr;
1613 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1614 NULL, NULL);
1615 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1617 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1618 check_param("signed with auth attrs bare content", msg,
1619 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1620 sizeof(signedWithAuthAttrsBareContent));
1622 CryptMsgClose(msg);
1624 signer.cAuthAttr = 0;
1625 signInfo.rgCertEncoded = &encodedCert;
1626 signInfo.cCertEncoded = 1;
1627 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1628 NULL, NULL);
1629 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1631 check_param("signed with cert empty bare content", msg,
1632 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1633 sizeof(signedWithCertEmptyBareContent));
1634 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1635 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1636 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1637 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1639 CryptMsgClose(msg);
1641 signInfo.cCertEncoded = 0;
1642 signInfo.rgCrlEncoded = &encodedCrl;
1643 signInfo.cCrlEncoded = 1;
1644 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1645 NULL, NULL);
1646 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1648 check_param("signed with crl empty bare content", msg,
1649 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1650 sizeof(signedWithCrlEmptyBareContent));
1651 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1652 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1653 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1654 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1656 CryptMsgClose(msg);
1658 signInfo.cCertEncoded = 1;
1659 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1660 NULL, NULL);
1661 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1663 check_param("signed with cert and crl empty bare content", msg,
1664 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1665 sizeof(signedWithCertAndCrlEmptyBareContent));
1666 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1667 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1668 check_param("signed with cert and crl bare content", msg,
1669 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1670 sizeof(signedWithCertAndCrlBareContent));
1672 CryptMsgClose(msg);
1674 /* Test with a cert with a (bogus) public key */
1675 signInfo.cCrlEncoded = 0;
1676 encodedCert.cbData = sizeof(v1CertWithPubKey);
1677 encodedCert.pbData = v1CertWithPubKey;
1678 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1679 NULL, NULL);
1680 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1681 check_param("signedWithCertWithPubKeyBareContent", msg,
1682 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1683 sizeof(signedWithCertWithPubKeyBareContent));
1684 CryptMsgClose(msg);
1686 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1687 encodedCert.pbData = v1CertWithValidPubKey;
1688 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1689 NULL, NULL);
1690 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1691 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1692 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1693 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1694 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1695 check_param("signedWithCertWithValidPubKeyContent", msg,
1696 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1697 sizeof(signedWithCertWithValidPubKeyContent));
1698 CryptMsgClose(msg);
1700 CryptDestroyKey(key);
1701 CryptReleaseContext(signer.hCryptProv, 0);
1702 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1703 CRYPT_DELETEKEYSET);
1706 static void test_signed_msg_get_param(void)
1708 BOOL ret;
1709 HCRYPTMSG msg;
1710 DWORD size, value = 0;
1711 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1712 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1713 CERT_INFO certInfo = { 0 };
1715 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1716 NULL, NULL);
1717 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1719 /* Content and bare content are always gettable */
1720 size = 0;
1721 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1722 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1723 size = 0;
1724 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1725 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1726 /* For "signed" messages, so is the version. */
1727 size = 0;
1728 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1729 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1730 size = sizeof(value);
1731 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1732 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1733 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1734 /* But for this message, with no signers, the hash and signer aren't
1735 * available.
1737 size = 0;
1738 SetLastError(0xdeadbeef);
1739 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1740 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1741 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1742 SetLastError(0xdeadbeef);
1743 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1744 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1745 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1746 /* As usual, the type isn't available. */
1747 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1748 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1749 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1751 CryptMsgClose(msg);
1753 certInfo.SerialNumber.cbData = sizeof(serialNum);
1754 certInfo.SerialNumber.pbData = serialNum;
1755 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1756 certInfo.Issuer.pbData = encodedCommonName;
1757 signer.pCertInfo = &certInfo;
1758 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1759 signInfo.cSigners = 1;
1760 signInfo.rgSigners = &signer;
1761 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1762 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1763 if (!ret && GetLastError() == NTE_EXISTS)
1764 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1765 PROV_RSA_FULL, 0);
1766 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1767 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1768 NULL, NULL);
1769 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1771 /* This message, with one signer, has the hash and signer for index 0
1772 * available, but not for other indexes.
1774 size = 0;
1775 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1776 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1777 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1778 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1779 size = 0;
1780 SetLastError(0xdeadbeef);
1781 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1782 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1783 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1784 SetLastError(0xdeadbeef);
1785 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1786 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1787 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1788 /* As usual, the type isn't available. */
1789 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1790 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1791 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1793 CryptMsgClose(msg);
1795 CryptReleaseContext(signer.hCryptProv, 0);
1796 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1797 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1800 static void test_signed_msg(void)
1802 test_signed_msg_open();
1803 test_signed_msg_update();
1804 test_signed_msg_encoding();
1805 test_signed_msg_get_param();
1808 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1809 static const struct update_accum a4 = { 1, &b4 };
1811 static const BYTE bogusOIDContent[] = {
1812 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1813 0x04,0x00 };
1814 static const BYTE bogusHashContent[] = {
1815 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1816 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1817 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1818 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1819 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1821 static void test_decode_msg_update(void)
1823 HCRYPTMSG msg;
1824 BOOL ret;
1825 CMSG_STREAM_INFO streamInfo = { 0 };
1826 DWORD i;
1827 struct update_accum accum = { 0, NULL };
1829 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1830 /* Update with a full message in a final update */
1831 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1832 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1833 /* Can't update after a final update */
1834 SetLastError(0xdeadbeef);
1835 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1836 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1837 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1838 CryptMsgClose(msg);
1840 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1841 /* Can't send a non-final update without streaming */
1842 SetLastError(0xdeadbeef);
1843 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1844 FALSE);
1845 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1846 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1847 /* A subsequent final update succeeds */
1848 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1849 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1850 CryptMsgClose(msg);
1852 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1853 /* Updating a message that has a NULL stream callback fails */
1854 SetLastError(0xdeadbeef);
1855 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1856 FALSE);
1857 todo_wine
1858 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1859 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1860 /* Changing the callback pointer after the fact yields the same error (so
1861 * the message must copy the stream info, not just store a pointer to it)
1863 streamInfo.pfnStreamOutput = nop_stream_output;
1864 SetLastError(0xdeadbeef);
1865 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1866 FALSE);
1867 todo_wine
1868 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1869 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1870 CryptMsgClose(msg);
1872 /* Empty non-final updates are allowed when streaming.. */
1873 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1874 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1875 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1876 /* but final updates aren't when not enough data has been received. */
1877 SetLastError(0xdeadbeef);
1878 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1879 todo_wine
1880 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1881 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1882 CryptMsgClose(msg);
1884 /* Updating the message byte by byte is legal */
1885 streamInfo.pfnStreamOutput = accumulating_stream_output;
1886 streamInfo.pvArg = &accum;
1887 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1888 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1889 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1890 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1891 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1892 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1893 CryptMsgClose(msg);
1894 todo_wine
1895 check_updates("byte-by-byte empty content", &a4, &accum);
1896 free_updates(&accum);
1898 /* Decoding bogus content fails in non-streaming mode.. */
1899 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1900 SetLastError(0xdeadbeef);
1901 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1902 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1903 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1904 CryptMsgClose(msg);
1905 /* and as the final update in streaming mode.. */
1906 streamInfo.pfnStreamOutput = nop_stream_output;
1907 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1908 SetLastError(0xdeadbeef);
1909 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1910 todo_wine
1911 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1912 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1913 CryptMsgClose(msg);
1914 /* and even as a non-final update in streaming mode. */
1915 streamInfo.pfnStreamOutput = nop_stream_output;
1916 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1917 SetLastError(0xdeadbeef);
1918 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1919 todo_wine
1920 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1921 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1922 CryptMsgClose(msg);
1924 /* An empty message can be opened with undetermined type.. */
1925 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1926 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1927 TRUE);
1928 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1929 CryptMsgClose(msg);
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());
2451 CryptMsgClose(msg);
2454 static void test_msg_get_signer_count(void)
2456 LONG count;
2458 SetLastError(0xdeadbeef);
2459 count = CryptGetMessageSignerCount(0, NULL, 0);
2460 ok(count == -1, "Expected -1, got %d\n", count);
2461 ok(GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n",
2462 GetLastError());
2463 SetLastError(0xdeadbeef);
2464 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, NULL, 0);
2465 ok(count == -1, "Expected -1, got %d\n", count);
2466 ok(GetLastError() == CRYPT_E_ASN1_EOD,
2467 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2468 SetLastError(0xdeadbeef);
2469 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2470 dataEmptyBareContent, sizeof(dataEmptyBareContent));
2471 ok(count == -1, "Expected -1, got %d\n", count);
2472 ok(GetLastError() == CRYPT_E_ASN1_BADTAG,
2473 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2474 SetLastError(0xdeadbeef);
2475 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2476 dataEmptyContent, sizeof(dataEmptyContent));
2477 ok(count == -1, "Expected -1, got %d\n", count);
2478 ok(GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2479 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2480 SetLastError(0xdeadbeef);
2481 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2482 signedEmptyBareContent, sizeof(signedEmptyBareContent));
2483 ok(count == -1, "Expected -1, got %d\n", count);
2484 ok(GetLastError() == CRYPT_E_ASN1_BADTAG,
2485 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2486 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2487 signedEmptyContent, sizeof(signedEmptyContent));
2488 ok(count == 1, "Expected 1, got %d\n", count);
2491 static const BYTE signedWithCertEmptyContent[] = {
2492 0x30,0x81,0xdf,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
2493 0x81,0xd1,0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
2494 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,
2495 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2496 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2497 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2498 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2499 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2500 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2501 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
2502 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2503 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
2504 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
2505 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
2506 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
2507 0x00 };
2508 static const BYTE signedWithCertContent[] = {
2509 0x30,0x82,0x01,0x32,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
2510 0xa0,0x82,0x01,0x23,0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
2511 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
2512 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
2513 0x02,0x03,0x04,0xa0,0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
2514 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
2515 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
2516 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
2517 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
2518 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
2519 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
2520 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
2521 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,
2522 0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,
2523 0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,
2524 0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,
2525 0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,
2526 0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,
2527 0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,
2528 0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,
2529 0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
2530 static const BYTE signedWithCertWithPubKeyContent[] = {
2531 0x30,0x81,0xfc,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
2532 0x81,0xee,0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
2533 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,
2534 0x98,0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,
2535 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
2536 0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2537 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
2538 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,
2539 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2540 0x6e,0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2541 0x01,0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
2542 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,
2543 0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,
2544 0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
2545 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2546 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
2547 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
2549 static void test_verify_message_signature(void)
2551 BOOL ret;
2552 CRYPT_VERIFY_MESSAGE_PARA para = { 0 };
2553 PCCERT_CONTEXT cert;
2554 DWORD cbDecoded;
2556 SetLastError(0xdeadbeef);
2557 ret = CryptVerifyMessageSignature(NULL, 0, NULL, 0, NULL, 0, NULL);
2558 ok(!ret && GetLastError() == E_INVALIDARG,
2559 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2560 SetLastError(0xdeadbeef);
2561 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2562 ok(!ret && GetLastError() == E_INVALIDARG,
2563 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2564 para.cbSize = sizeof(para);
2565 SetLastError(0xdeadbeef);
2566 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2567 ok(!ret && GetLastError() == E_INVALIDARG,
2568 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2569 para.cbSize = 0;
2570 para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING;
2571 SetLastError(0xdeadbeef);
2572 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2573 ok(!ret && GetLastError() == E_INVALIDARG,
2574 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2575 para.cbSize = sizeof(para);
2576 SetLastError(0xdeadbeef);
2577 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2578 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2579 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2580 /* Check whether cert is set on error */
2581 cert = (PCCERT_CONTEXT)0xdeadbeef;
2582 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, &cert);
2583 ok(cert == NULL, "Expected NULL cert\n");
2584 /* Check whether cbDecoded is set on error */
2585 cbDecoded = 0xdeadbeef;
2586 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, &cbDecoded,
2587 NULL);
2588 ok(!cbDecoded, "Expected 0\n");
2589 SetLastError(0xdeadbeef);
2590 ret = CryptVerifyMessageSignature(&para, 0, dataEmptyBareContent,
2591 sizeof(dataEmptyBareContent), NULL, 0, NULL);
2592 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2593 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2594 SetLastError(0xdeadbeef);
2595 ret = CryptVerifyMessageSignature(&para, 0, dataEmptyContent,
2596 sizeof(dataEmptyContent), NULL, 0, NULL);
2597 ok(!ret && GetLastError() == CRYPT_E_UNEXPECTED_MSG_TYPE,
2598 "Expected CRYPT_E_UNEXPECTED_MSG_TYPE, got %08x\n", GetLastError());
2599 SetLastError(0xdeadbeef);
2600 ret = CryptVerifyMessageSignature(&para, 0, signedEmptyBareContent,
2601 sizeof(signedEmptyBareContent), NULL, 0, NULL);
2602 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2603 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2604 SetLastError(0xdeadbeef);
2605 ret = CryptVerifyMessageSignature(&para, 0, signedEmptyContent,
2606 sizeof(signedEmptyContent), NULL, 0, NULL);
2607 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2608 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2609 SetLastError(0xdeadbeef);
2610 ret = CryptVerifyMessageSignature(&para, 0, signedContent,
2611 sizeof(signedContent), NULL, 0, NULL);
2612 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2613 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2614 /* FIXME: Windows fails with CRYPT_E_NOT_FOUND for these messages, but
2615 * their signer certs have invalid public keys that fail to decode. In
2616 * Wine therefore the failure is an ASN error. Need some messages with
2617 * valid public keys and invalid signatures to check against.
2619 ret = CryptVerifyMessageSignature(&para, 0, signedWithCertEmptyContent,
2620 sizeof(signedWithCertEmptyContent), NULL, 0, NULL);
2621 ok(!ret, "Expected failure\n");
2622 ret = CryptVerifyMessageSignature(&para, 0, signedWithCertContent,
2623 sizeof(signedWithCertContent), NULL, 0, NULL);
2624 ok(!ret, "Expected failure\n");
2625 ret = CryptVerifyMessageSignature(&para, 0, signedWithCertWithPubKeyContent,
2626 sizeof(signedWithCertWithPubKeyContent), NULL, 0, NULL);
2627 ok(!ret, "Expected failure\n");
2630 START_TEST(msg)
2632 init_function_pointers();
2634 /* Basic parameter checking tests */
2635 test_msg_open_to_encode();
2636 test_msg_open_to_decode();
2637 test_msg_get_param();
2638 test_msg_close();
2639 test_msg_control();
2641 /* Message-type specific tests */
2642 test_data_msg();
2643 test_hash_msg();
2644 test_signed_msg();
2645 test_decode_msg();
2647 /* simplified message functions */
2648 test_msg_get_signer_count();
2649 test_verify_message_signature();