push 6495605bb529da27066f1c178d57d902552737a0
[wine/hacks.git] / dlls / crypt32 / tests / msg.c
blob0f7dcb6860d61e126c8e652e2116e8dbb93f9a93
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 BOOL have_nt;
31 static char oid_rsa_md5[] = szOID_RSA_MD5;
33 static BOOL (WINAPI * pCryptAcquireContextA)
34 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
35 static BOOL (WINAPI * pCryptAcquireContextW)
36 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
38 static void init_function_pointers(void)
40 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
42 #define GET_PROC(dll, func) \
43 p ## func = (void *)GetProcAddress(dll, #func); \
44 if(!p ## func) \
45 trace("GetProcAddress(%s) failed\n", #func);
47 GET_PROC(hAdvapi32, CryptAcquireContextA)
48 GET_PROC(hAdvapi32, CryptAcquireContextW)
50 #undef GET_PROC
53 static void test_msg_open_to_encode(void)
55 HCRYPTMSG msg;
57 /* Crash
58 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
59 NULL, NULL);
60 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
61 NULL);
62 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
63 NULL);
66 /* Bad encodings */
67 SetLastError(0xdeadbeef);
68 msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
69 ok(!msg && GetLastError() == E_INVALIDARG,
70 "Expected E_INVALIDARG, got %x\n", GetLastError());
71 SetLastError(0xdeadbeef);
72 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
73 ok(!msg && GetLastError() == E_INVALIDARG,
74 "Expected E_INVALIDARG, got %x\n", GetLastError());
76 /* Bad message types */
77 SetLastError(0xdeadbeef);
78 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
79 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
80 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
81 SetLastError(0xdeadbeef);
82 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
83 NULL, NULL, NULL);
84 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
85 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
86 SetLastError(0xdeadbeef);
87 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
88 CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
89 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
90 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
91 SetLastError(0xdeadbeef);
92 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
93 NULL, NULL);
94 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
95 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
98 static void test_msg_open_to_decode(void)
100 HCRYPTMSG msg;
101 CMSG_STREAM_INFO streamInfo = { 0 };
103 SetLastError(0xdeadbeef);
104 msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
105 ok(!msg && GetLastError() == E_INVALIDARG,
106 "Expected E_INVALIDARG, got %x\n", GetLastError());
108 /* Bad encodings */
109 SetLastError(0xdeadbeef);
110 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
111 ok(!msg && GetLastError() == E_INVALIDARG,
112 "Expected E_INVALIDARG, got %x\n", GetLastError());
113 SetLastError(0xdeadbeef);
114 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
115 ok(!msg && GetLastError() == E_INVALIDARG,
116 "Expected E_INVALIDARG, got %x\n", GetLastError());
118 /* The message type can be explicit... */
119 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 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_ENVELOPED, 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_HASHED, 0, NULL,
128 NULL);
129 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
130 CryptMsgClose(msg);
131 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
132 NULL);
133 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
134 CryptMsgClose(msg);
135 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
136 CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
137 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
138 CryptMsgClose(msg);
139 /* or implicit.. */
140 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
141 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
142 CryptMsgClose(msg);
143 /* or even invalid. */
144 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
145 NULL);
146 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
147 CryptMsgClose(msg);
148 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
149 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
150 CryptMsgClose(msg);
152 /* And even though the stream info parameter "must be set to NULL" for
153 * CMSG_HASHED, it's still accepted.
155 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
156 &streamInfo);
157 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
158 CryptMsgClose(msg);
161 static void test_msg_get_param(void)
163 BOOL ret;
164 HCRYPTMSG msg;
165 DWORD size, i, value;
166 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
167 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
169 /* Crash
170 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
171 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
172 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
175 /* Decoded messages */
176 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
177 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
178 /* For decoded messages, the type is always available */
179 size = 0;
180 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
181 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
182 size = sizeof(value);
183 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
184 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
185 /* For this (empty) message, the type isn't set */
186 ok(value == 0, "Expected type 0, got %d\n", value);
187 CryptMsgClose(msg);
189 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
190 NULL);
191 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
192 /* For explicitly typed messages, the type is known. */
193 size = sizeof(value);
194 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
195 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
196 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
197 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
199 size = 0;
200 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
201 ok(!ret, "Parameter %d: expected failure\n", i);
203 CryptMsgClose(msg);
205 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
206 NULL);
207 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
208 size = sizeof(value);
209 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
210 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
211 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
212 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
214 size = 0;
215 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
216 ok(!ret, "Parameter %d: expected failure\n", i);
218 CryptMsgClose(msg);
220 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
221 NULL);
222 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
223 size = sizeof(value);
224 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
225 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
226 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
227 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
229 size = 0;
230 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
231 ok(!ret, "Parameter %d: expected failure\n", i);
233 CryptMsgClose(msg);
235 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
236 NULL);
237 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
238 size = sizeof(value);
239 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
240 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
241 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
242 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
244 size = 0;
245 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
246 ok(!ret, "Parameter %d: expected failure\n", i);
248 CryptMsgClose(msg);
250 /* Explicitly typed messages get their types set, even if they're invalid */
251 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
252 NULL);
253 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
254 size = sizeof(value);
255 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
256 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
257 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
258 CryptMsgClose(msg);
260 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
261 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
262 size = sizeof(value);
263 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
264 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
265 ok(value == 1000, "Expected 1000, got %d\n", value);
266 CryptMsgClose(msg);
269 static void test_msg_close(void)
271 BOOL ret;
272 HCRYPTMSG msg;
274 /* NULL succeeds.. */
275 ret = CryptMsgClose(NULL);
276 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
277 /* but an arbitrary pointer crashes. */
278 if (0)
279 ret = CryptMsgClose((HCRYPTMSG)1);
280 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
281 NULL);
282 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
283 ret = CryptMsgClose(msg);
284 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
287 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
288 const BYTE *expected, DWORD expectedSize)
290 DWORD size;
291 LPBYTE buf;
292 BOOL ret;
294 size = 0xdeadbeef;
295 ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
296 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
297 buf = HeapAlloc(GetProcessHeap(), 0, size);
298 ret = CryptMsgGetParam(msg, param, 0, buf, &size);
299 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
300 ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
301 expectedSize, size);
302 if (size == expectedSize && size)
303 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
304 HeapFree(GetProcessHeap(), 0, buf);
307 static void test_data_msg_open(void)
309 HCRYPTMSG msg;
310 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
311 CMSG_STREAM_INFO streamInfo = { 0 };
312 char oid[] = "1.2.3";
314 /* The data message type takes no additional info */
315 SetLastError(0xdeadbeef);
316 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
317 NULL, NULL);
318 ok(!msg && GetLastError() == E_INVALIDARG,
319 "Expected E_INVALIDARG, got %x\n", GetLastError());
320 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
321 NULL);
322 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
323 CryptMsgClose(msg);
325 /* An empty stream info is allowed. */
326 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
327 &streamInfo);
328 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
329 CryptMsgClose(msg);
331 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
332 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
333 NULL);
334 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
335 CryptMsgClose(msg);
336 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
337 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
338 CMSG_DATA, NULL, oid, NULL);
339 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
340 CryptMsgClose(msg);
341 /* and when a stream info is given, even though you're not supposed to be
342 * able to use anything but szOID_RSA_data when streaming is being used.
344 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
345 CMSG_DATA, NULL, oid, &streamInfo);
346 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
347 CryptMsgClose(msg);
350 static const BYTE msgData[] = { 1, 2, 3, 4 };
352 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
353 BOOL final)
355 return TRUE;
358 static void test_data_msg_update(void)
360 HCRYPTMSG msg;
361 BOOL ret;
362 CMSG_STREAM_INFO streamInfo = { 0 };
364 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
365 NULL);
366 /* Can't update a message that wasn't opened detached with final = FALSE */
367 SetLastError(0xdeadbeef);
368 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
369 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
370 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
371 /* Updating it with final = TRUE succeeds */
372 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
373 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
374 /* Any subsequent update will fail, as the last was final */
375 SetLastError(0xdeadbeef);
376 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
377 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
378 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
379 CryptMsgClose(msg);
381 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
382 NULL);
383 /* Can't update a message with no data */
384 SetLastError(0xdeadbeef);
385 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
386 /* This test returns FALSE on XP and earlier but TRUE on Vista, so can't be tested.
387 * GetLastError is either E_INVALIDARG (NT) or unset (9x/Vista), so it doesn't
388 * make sense to test this.
391 /* Curiously, a valid update will now fail as well, presumably because of
392 * the last (invalid, but final) update.
394 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
395 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
396 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
397 CryptMsgClose(msg);
399 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
400 CMSG_DATA, NULL, NULL, NULL);
401 /* Doesn't appear to be able to update CMSG-DATA with non-final updates */
402 SetLastError(0xdeadbeef);
403 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
404 ok(!ret && GetLastError() == E_INVALIDARG,
405 "Expected E_INVALIDARG, got %x\n", GetLastError());
406 SetLastError(0xdeadbeef);
407 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
408 ok(!ret && GetLastError() == E_INVALIDARG,
409 "Expected E_INVALIDARG, got %x\n", GetLastError());
410 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
411 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
412 CryptMsgClose(msg);
414 /* Calling update after opening with an empty stream info (with a bogus
415 * output function) yields an error:
417 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
418 &streamInfo);
419 SetLastError(0xdeadbeef);
420 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
421 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
422 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
423 CryptMsgClose(msg);
424 /* Calling update with a valid output function succeeds, even if the data
425 * exceeds the size specified in the stream info.
427 streamInfo.pfnStreamOutput = nop_stream_output;
428 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
429 &streamInfo);
430 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
431 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
432 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
433 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
434 CryptMsgClose(msg);
437 static void test_data_msg_get_param(void)
439 HCRYPTMSG msg;
440 DWORD size;
441 BOOL ret;
442 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
444 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
445 NULL);
447 /* Content and bare content are always gettable when not streaming */
448 size = 0;
449 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
450 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
451 size = 0;
452 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
453 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
454 /* But for this type of message, the signer and hash aren't applicable,
455 * and the type isn't available.
457 size = 0;
458 SetLastError(0xdeadbeef);
459 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
460 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
461 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
462 SetLastError(0xdeadbeef);
463 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
464 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
465 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
466 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
467 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
468 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
469 CryptMsgClose(msg);
471 /* Can't get content or bare content when streaming */
472 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
473 NULL, &streamInfo);
474 SetLastError(0xdeadbeef);
475 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
476 ok(!ret && GetLastError() == E_INVALIDARG,
477 "Expected E_INVALIDARG, got %x\n", GetLastError());
478 SetLastError(0xdeadbeef);
479 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
480 ok(!ret && GetLastError() == E_INVALIDARG,
481 "Expected E_INVALIDARG, got %x\n", GetLastError());
482 CryptMsgClose(msg);
485 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
486 static const BYTE dataEmptyContent[] = {
487 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
488 0x04,0x00 };
489 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
490 static const BYTE dataContent[] = {
491 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
492 0x04,0x04,0x01,0x02,0x03,0x04 };
494 struct update_accum
496 DWORD cUpdates;
497 CRYPT_DATA_BLOB *updates;
500 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
501 DWORD cb, BOOL final)
503 struct update_accum *accum = (struct update_accum *)pvArg;
504 BOOL ret = FALSE;
506 if (accum->cUpdates)
507 accum->updates = CryptMemRealloc(accum->updates,
508 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
509 else
510 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
511 if (accum->updates)
513 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
515 blob->pbData = CryptMemAlloc(cb);
516 if (blob->pbData)
518 memcpy(blob->pbData, pb, cb);
519 blob->cbData = cb;
520 ret = TRUE;
522 accum->cUpdates++;
524 return ret;
527 /* The updates of a (bogus) definite-length encoded message */
528 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
529 0x07,0x01,0xa0,0x02,0x04,0x00 };
530 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
531 static CRYPT_DATA_BLOB b1[] = {
532 { sizeof(u1), u1 },
533 { sizeof(u2), u2 },
534 { sizeof(u2), u2 },
536 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
537 /* The updates of a definite-length encoded message */
538 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
539 0x07,0x01,0xa0,0x06,0x04,0x04 };
540 static CRYPT_DATA_BLOB b2[] = {
541 { sizeof(u3), u3 },
542 { sizeof(u2), u2 },
544 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
545 /* The updates of an indefinite-length encoded message */
546 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
547 0x07,0x01,0xa0,0x80,0x24,0x80 };
548 static BYTE u5[] = { 0x04,0x04 };
549 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
550 static CRYPT_DATA_BLOB b3[] = {
551 { sizeof(u4), u4 },
552 { sizeof(u5), u5 },
553 { sizeof(u2), u2 },
554 { sizeof(u5), u5 },
555 { sizeof(u2), u2 },
556 { sizeof(u6), u6 },
558 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
560 static void check_updates(LPCSTR header, const struct update_accum *expected,
561 const struct update_accum *got)
563 DWORD i;
565 ok(expected->cUpdates == got->cUpdates,
566 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
567 got->cUpdates);
568 if (expected->cUpdates == got->cUpdates)
569 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
571 ok(expected->updates[i].cbData == got->updates[i].cbData,
572 "%s, update %d: expected %d bytes, got %d\n", header, i,
573 expected->updates[i].cbData, got->updates[i].cbData);
574 if (expected->updates[i].cbData && expected->updates[i].cbData ==
575 got->updates[i].cbData)
576 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
577 got->updates[i].cbData), "%s, update %d: unexpected value\n",
578 header, i);
582 /* Frees the updates stored in accum */
583 static void free_updates(struct update_accum *accum)
585 DWORD i;
587 for (i = 0; i < accum->cUpdates; i++)
588 CryptMemFree(accum->updates[i].pbData);
589 CryptMemFree(accum->updates);
590 accum->updates = NULL;
591 accum->cUpdates = 0;
594 static void test_data_msg_encoding(void)
596 HCRYPTMSG msg;
597 BOOL ret;
598 static char oid[] = "1.2.3";
599 struct update_accum accum = { 0, NULL };
600 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
602 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
603 NULL);
604 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
605 dataEmptyBareContent, sizeof(dataEmptyBareContent));
606 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
607 sizeof(dataEmptyContent));
608 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
609 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
610 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
611 dataBareContent, sizeof(dataBareContent));
612 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
613 sizeof(dataContent));
614 CryptMsgClose(msg);
615 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
616 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
617 CMSG_DATA, NULL, NULL, NULL);
618 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
619 dataEmptyBareContent, sizeof(dataEmptyBareContent));
620 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
621 sizeof(dataEmptyContent));
622 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
623 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
624 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
625 dataBareContent, sizeof(dataBareContent));
626 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
627 sizeof(dataContent));
628 CryptMsgClose(msg);
629 /* The inner OID is apparently ignored */
630 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
631 NULL);
632 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
633 dataEmptyBareContent, sizeof(dataEmptyBareContent));
634 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
635 dataEmptyContent, sizeof(dataEmptyContent));
636 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
637 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
638 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
639 dataBareContent, sizeof(dataBareContent));
640 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
641 sizeof(dataContent));
642 CryptMsgClose(msg);
643 /* A streaming message is DER encoded if the length is not 0xffffffff, but
644 * curiously, updates aren't validated to make sure they don't exceed the
645 * stated length. (The resulting output will of course fail to decode.)
647 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
648 NULL, &streamInfo);
649 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
650 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
651 CryptMsgClose(msg);
652 check_updates("bogus data message with definite length", &a1, &accum);
653 free_updates(&accum);
654 /* A valid definite-length encoding: */
655 streamInfo.cbContent = sizeof(msgData);
656 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
657 NULL, &streamInfo);
658 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
659 CryptMsgClose(msg);
660 check_updates("data message with definite length", &a2, &accum);
661 free_updates(&accum);
662 /* An indefinite-length encoding: */
663 streamInfo.cbContent = 0xffffffff;
664 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
665 NULL, &streamInfo);
666 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
667 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
668 CryptMsgClose(msg);
669 check_updates("data message with indefinite length", &a3, &accum);
670 free_updates(&accum);
673 static void test_data_msg(void)
675 test_data_msg_open();
676 test_data_msg_update();
677 test_data_msg_get_param();
678 test_data_msg_encoding();
681 static void test_hash_msg_open(void)
683 HCRYPTMSG msg;
684 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
685 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
687 SetLastError(0xdeadbeef);
688 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
689 NULL, NULL);
690 ok(!msg && GetLastError() == E_INVALIDARG,
691 "Expected E_INVALIDARG, got %x\n", GetLastError());
692 hashInfo.cbSize = sizeof(hashInfo);
693 SetLastError(0xdeadbeef);
694 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
695 NULL, NULL);
696 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
697 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
698 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
699 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
700 NULL, NULL);
701 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
702 CryptMsgClose(msg);
703 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
704 CMSG_HASHED, &hashInfo, NULL, NULL);
705 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
706 CryptMsgClose(msg);
707 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
708 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
709 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
710 CryptMsgClose(msg);
713 static void test_hash_msg_update(void)
715 HCRYPTMSG msg;
716 BOOL ret;
717 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
718 { oid_rsa_md5, { 0, NULL } }, NULL };
719 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
721 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
722 CMSG_HASHED, &hashInfo, NULL, NULL);
723 /* Detached hashed messages opened in non-streaming mode allow non-final
724 * updates..
726 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
727 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
728 /* including non-final updates with no data.. */
729 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
730 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
731 /* and final updates with no data. */
732 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
733 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
734 /* But no updates are allowed after the final update. */
735 SetLastError(0xdeadbeef);
736 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
737 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
738 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
739 SetLastError(0xdeadbeef);
740 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
741 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
742 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
743 CryptMsgClose(msg);
744 /* Non-detached messages, in contrast, don't allow non-final updates in
745 * non-streaming mode.
747 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
748 NULL, NULL);
749 SetLastError(0xdeadbeef);
750 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
751 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
752 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
753 /* Final updates (including empty ones) are allowed. */
754 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
755 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
756 CryptMsgClose(msg);
757 /* And, of course, streaming mode allows non-final updates */
758 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
759 NULL, &streamInfo);
760 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
761 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
762 CryptMsgClose(msg);
763 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
764 * to be a bug, it isn't actually used - see encoding tests.)
766 streamInfo.pfnStreamOutput = NULL;
767 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
768 NULL, &streamInfo);
769 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
770 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
771 CryptMsgClose(msg);
774 static const BYTE emptyHashParam[] = {
775 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
776 0x7e };
778 static void test_hash_msg_get_param(void)
780 HCRYPTMSG msg;
781 BOOL ret;
782 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
783 { oid_rsa_md5, { 0, NULL } }, NULL };
784 DWORD size, value;
785 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
786 BYTE buf[16];
788 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
789 NULL, NULL);
790 /* Content and bare content are always gettable for non-streamed messages */
791 size = 0;
792 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
793 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
794 size = 0;
795 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
796 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
797 /* For an encoded hash message, the hash data aren't available */
798 SetLastError(0xdeadbeef);
799 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
800 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
801 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
802 /* The hash is also available. */
803 size = 0;
804 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
805 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
806 ok(size == sizeof(buf), "Unexpected size %d\n", size);
807 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
808 if (size == sizeof(buf))
809 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
810 /* By getting the hash, further updates are not allowed */
811 SetLastError(0xdeadbeef);
812 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
813 ok(!ret &&
814 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
815 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
816 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */),
817 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
819 /* Even after a final update, the hash data aren't available */
820 SetLastError(0xdeadbeef);
821 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
822 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
823 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
824 /* The version is also available, and should be zero for this message. */
825 size = 0;
826 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
827 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
828 size = sizeof(value);
829 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
830 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
831 ok(value == 0, "Expected version 0, got %d\n", value);
832 /* As usual, the type isn't available. */
833 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
834 ok(!ret, "Expected failure\n");
835 CryptMsgClose(msg);
837 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
838 NULL, &streamInfo);
839 /* Streamed messages don't allow you to get the content or bare content. */
840 SetLastError(0xdeadbeef);
841 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
842 ok(!ret && GetLastError() == E_INVALIDARG,
843 "Expected E_INVALIDARG, got %x\n", GetLastError());
844 SetLastError(0xdeadbeef);
845 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
846 ok(!ret && GetLastError() == E_INVALIDARG,
847 "Expected E_INVALIDARG, got %x\n", GetLastError());
848 /* The hash is still available. */
849 size = 0;
850 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
851 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
852 ok(size == sizeof(buf), "Unexpected size %d\n", size);
853 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
854 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
855 if (size == sizeof(buf))
856 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
857 /* After updating the hash, further updates aren't allowed on streamed
858 * messages either.
860 SetLastError(0xdeadbeef);
861 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
862 ok(!ret &&
863 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
864 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
865 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */),
866 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
868 CryptMsgClose(msg);
871 static const BYTE hashEmptyBareContent[] = {
872 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
873 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
874 static const BYTE hashEmptyContent[] = {
875 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
876 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
877 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
878 static const BYTE hashBareContent[] = {
879 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
880 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
881 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
882 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
883 static const BYTE hashContent[] = {
884 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
885 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
886 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
887 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
888 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
890 static const BYTE detachedHashNonFinalBareContent[] = {
891 0x30,0x20,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,0x00 };
894 static const BYTE detachedHashNonFinalContent[] = {
895 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
896 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
897 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
898 0x07,0x01,0x04,0x00 };
899 static const BYTE detachedHashBareContent[] = {
900 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
901 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
902 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
903 0x9d,0x2a,0x8f,0x26,0x2f };
904 static const BYTE detachedHashContent[] = {
905 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
906 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
907 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
908 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
909 0x9d,0x2a,0x8f,0x26,0x2f };
911 static void test_hash_msg_encoding(void)
913 HCRYPTMSG msg;
914 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
915 BOOL ret;
916 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
917 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
919 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
920 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
921 NULL, NULL);
922 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
923 hashEmptyBareContent, sizeof(hashEmptyBareContent));
924 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
925 hashEmptyContent, sizeof(hashEmptyContent));
926 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
927 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
928 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
929 hashBareContent, sizeof(hashBareContent));
930 check_param("hash content", msg, CMSG_CONTENT_PARAM,
931 hashContent, sizeof(hashContent));
932 CryptMsgClose(msg);
933 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
934 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
935 CMSG_HASHED, &hashInfo, NULL, NULL);
936 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
937 hashEmptyBareContent, sizeof(hashEmptyBareContent));
938 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
939 hashEmptyContent, sizeof(hashEmptyContent));
940 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
941 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
942 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
943 hashBareContent, sizeof(hashBareContent));
944 check_param("hash content", msg, CMSG_CONTENT_PARAM,
945 hashContent, sizeof(hashContent));
946 CryptMsgClose(msg);
947 /* Same test, but with CMSG_DETACHED_FLAG set */
948 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
949 CMSG_HASHED, &hashInfo, NULL, NULL);
950 check_param("detached hash empty bare content", msg,
951 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
952 sizeof(hashEmptyBareContent));
953 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
954 hashEmptyContent, sizeof(hashEmptyContent));
955 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
956 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
957 check_param("detached hash not final bare content", msg,
958 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
959 sizeof(detachedHashNonFinalBareContent));
960 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
961 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
962 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
963 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
964 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
965 detachedHashBareContent, sizeof(detachedHashBareContent));
966 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
967 detachedHashContent, sizeof(detachedHashContent));
968 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
969 detachedHashBareContent, sizeof(detachedHashBareContent));
970 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
971 detachedHashContent, sizeof(detachedHashContent));
972 CryptMsgClose(msg);
973 /* In what appears to be a bug, streamed updates to hash messages don't
974 * call the output function.
976 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
977 NULL, &streamInfo);
978 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
979 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
980 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
981 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
982 CryptMsgClose(msg);
983 check_updates("empty hash message", &empty_accum, &accum);
984 free_updates(&accum);
986 streamInfo.cbContent = sizeof(msgData);
987 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
988 NULL, &streamInfo);
989 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
990 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
991 CryptMsgClose(msg);
992 check_updates("hash message", &empty_accum, &accum);
993 free_updates(&accum);
995 streamInfo.cbContent = sizeof(msgData);
996 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
997 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
998 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
999 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1000 CryptMsgClose(msg);
1001 check_updates("detached hash message", &empty_accum, &accum);
1002 free_updates(&accum);
1005 static void test_hash_msg(void)
1007 test_hash_msg_open();
1008 test_hash_msg_update();
1009 test_hash_msg_get_param();
1010 test_hash_msg_encoding();
1013 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1014 'm','p',0 };
1015 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1016 'm','p',0 };
1017 static BYTE serialNum[] = { 1 };
1018 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1019 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1021 static void test_signed_msg_open(void)
1023 HCRYPTMSG msg;
1024 BOOL ret;
1025 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1026 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1027 CERT_INFO certInfo = { 0 };
1029 SetLastError(0xdeadbeef);
1030 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1031 NULL, NULL);
1032 ok(!msg && GetLastError() == E_INVALIDARG,
1033 "Expected E_INVALIDARG, got %x\n", GetLastError());
1034 signInfo.cbSize = sizeof(signInfo);
1035 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1036 NULL, NULL);
1037 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1038 CryptMsgClose(msg);
1040 signInfo.cSigners = 1;
1041 signInfo.rgSigners = &signer;
1042 /* With signer.pCertInfo unset, attempting to open this message this
1043 * crashes.
1045 signer.pCertInfo = &certInfo;
1046 /* The cert info must contain a serial number and an issuer. */
1047 SetLastError(0xdeadbeef);
1048 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1049 NULL, NULL);
1050 /* NT: E_INVALIDARG, 9x: unchanged */
1051 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef),
1052 "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError());
1054 certInfo.SerialNumber.cbData = sizeof(serialNum);
1055 certInfo.SerialNumber.pbData = serialNum;
1056 SetLastError(0xdeadbeef);
1057 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1058 NULL, NULL);
1059 /* NT: E_INVALIDARG, 9x: unchanged */
1060 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef),
1061 "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError());
1063 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1064 certInfo.Issuer.pbData = encodedCommonName;
1065 SetLastError(0xdeadbeef);
1066 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1067 NULL, NULL);
1068 ok(!msg && GetLastError() == E_INVALIDARG,
1069 "Expected E_INVALIDARG, got %x\n", GetLastError());
1071 /* The signer's hCryptProv must be set to something. Whether it's usable
1072 * or not will be checked after the hash algorithm is checked (see next
1073 * test.)
1075 signer.hCryptProv = 1;
1076 SetLastError(0xdeadbeef);
1077 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1078 NULL, NULL);
1079 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1080 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1081 /* The signer's hash algorithm must also be set. */
1082 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1083 SetLastError(0xdeadbeef);
1084 /* Crashes in advapi32 in wine, don't do it */
1085 if (0) {
1086 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1087 &signInfo, NULL, NULL);
1088 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1089 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1091 /* The signer's hCryptProv must also be valid. */
1092 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1093 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1094 if (!ret && GetLastError() == NTE_EXISTS) {
1095 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1096 PROV_RSA_FULL, 0);
1098 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1100 if (ret) {
1101 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1102 NULL, NULL);
1103 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1104 CryptMsgClose(msg);
1107 CryptReleaseContext(signer.hCryptProv, 0);
1108 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1109 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1112 static const BYTE privKey[] = {
1113 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1114 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1115 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1116 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1117 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1118 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1119 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1120 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1121 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1122 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1123 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1124 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1125 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1126 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1127 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1128 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1129 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1130 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1131 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1132 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1133 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1134 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1135 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1136 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1137 static BYTE pubKey[] = {
1138 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1139 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1140 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1141 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1142 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1144 static void test_signed_msg_update(void)
1146 HCRYPTMSG msg;
1147 BOOL ret;
1148 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1149 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1150 CERT_INFO certInfo = { 0 };
1151 HCRYPTKEY key;
1153 certInfo.SerialNumber.cbData = sizeof(serialNum);
1154 certInfo.SerialNumber.pbData = serialNum;
1155 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1156 certInfo.Issuer.pbData = encodedCommonName;
1157 signer.pCertInfo = &certInfo;
1158 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1159 signInfo.cSigners = 1;
1160 signInfo.rgSigners = &signer;
1162 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1163 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1164 if (!ret && GetLastError() == NTE_EXISTS) {
1165 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1166 PROV_RSA_FULL, 0);
1168 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1170 if (!ret) {
1171 skip("No context for tests\n");
1172 return;
1175 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1176 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1177 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1178 /* Detached CMSG_SIGNED allows non-final updates. */
1179 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1180 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1181 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1182 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1183 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1184 /* The final update requires a private key in the hCryptProv, in order to
1185 * generate the signature.
1187 SetLastError(0xdeadbeef);
1188 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1189 ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1190 GetLastError() == NTE_NO_KEY),
1191 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1192 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1193 0, 0, &key);
1194 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1195 /* The final update should be able to succeed now that a key exists, but
1196 * the previous (invalid) final update prevents it.
1198 SetLastError(0xdeadbeef);
1199 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1200 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1201 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1202 CryptMsgClose(msg);
1204 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1205 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1206 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1207 /* Detached CMSG_SIGNED allows non-final updates. */
1208 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1209 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1210 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1211 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1212 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1213 /* Now that the private key exists, the final update can succeed (even
1214 * with no data.)
1216 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1217 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1218 /* But no updates are allowed after the final update. */
1219 SetLastError(0xdeadbeef);
1220 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1221 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1222 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1223 SetLastError(0xdeadbeef);
1224 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1225 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1226 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1227 CryptMsgClose(msg);
1229 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1230 NULL, NULL);
1231 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1232 /* Non-detached messages don't allow non-final updates.. */
1233 SetLastError(0xdeadbeef);
1234 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1235 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1236 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1237 /* but they do allow final ones. */
1238 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1239 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1240 CryptMsgClose(msg);
1241 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1242 NULL, NULL);
1243 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1244 /* They also allow final updates with no data. */
1245 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1246 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1247 CryptMsgClose(msg);
1249 CryptDestroyKey(key);
1250 CryptReleaseContext(signer.hCryptProv, 0);
1251 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1252 CRYPT_DELETEKEYSET);
1255 static const BYTE signedEmptyBareContent[] = {
1256 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1257 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1258 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1259 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1260 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1261 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1262 static const BYTE signedEmptyContent[] = {
1263 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1264 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1265 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1266 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1267 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1268 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1269 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1270 static const BYTE detachedSignedBareContent[] = {
1271 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1272 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1273 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1274 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1275 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1276 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1277 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1278 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1279 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1280 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1281 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1282 static const BYTE detachedSignedContent[] = {
1283 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1284 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1285 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1286 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1287 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1288 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1289 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1290 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1291 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1292 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1293 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1294 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1295 static const BYTE signedBareContent[] = {
1296 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1297 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1298 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1299 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1300 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1301 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1302 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1303 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1304 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1305 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1306 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1307 static const BYTE signedContent[] = {
1308 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1309 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1310 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1311 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1312 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1313 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1314 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1315 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1316 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1317 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1318 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1319 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1320 0x0d };
1321 static const BYTE signedHash[] = {
1322 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1323 0x2f };
1324 static const BYTE signedEncodedSigner[] = {
1325 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1326 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1327 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1328 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1329 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1330 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1331 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1332 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1333 static const BYTE signedWithAuthAttrsBareContent[] = {
1334 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1335 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1336 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1337 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1338 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1339 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1340 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1341 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1342 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1343 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1344 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1345 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1346 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1347 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1348 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1349 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1350 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1351 0xff,0xc6,0x33,0x63,0x34 };
1352 static BYTE cert[] = {
1353 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1354 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1355 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1356 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1357 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1358 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1359 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1360 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1361 0xff,0x02,0x01,0x01 };
1362 static BYTE v1CertWithPubKey[] = {
1363 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1364 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1365 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1366 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1367 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1368 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1369 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1370 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1371 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1372 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1373 0x01,0x01 };
1374 static const BYTE signedWithCertEmptyBareContent[] = {
1375 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1376 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1377 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1378 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1379 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1380 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1381 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1382 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1383 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1384 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1385 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1386 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1387 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1388 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1389 static const BYTE signedWithCertBareContent[] = {
1390 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1391 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1392 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1393 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1394 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1395 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1396 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1397 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1398 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1399 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1400 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1401 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1402 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1403 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1404 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1405 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1406 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1407 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1408 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1409 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1410 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1411 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1412 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1413 0x30,0x30,0x30,0x30,0x5a };
1414 static const BYTE signedWithCrlEmptyBareContent[] = {
1415 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1416 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1417 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1418 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1419 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1420 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1421 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1422 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1423 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1424 static const BYTE signedWithCrlBareContent[] = {
1425 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1426 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1427 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1428 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1429 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1430 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1431 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1432 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1433 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1434 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1435 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1436 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1437 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1438 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1439 0xa8,0x0d };
1440 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1441 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1442 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1443 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1444 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1445 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1446 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1447 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1448 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1449 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1450 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1451 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1452 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1453 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1454 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1455 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1456 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1457 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1458 0x04,0x00 };
1459 static const BYTE signedWithCertAndCrlBareContent[] = {
1460 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1461 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1462 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1463 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,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,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1466 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1467 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1468 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1469 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1470 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1471 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1472 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1473 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1474 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1475 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1476 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1477 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1478 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1479 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1480 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1481 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1482 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1483 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1484 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1485 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1486 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1487 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1488 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1489 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1490 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1491 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1492 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1493 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1494 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1495 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1496 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1497 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1498 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1499 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1500 static BYTE v1CertWithValidPubKey[] = {
1501 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1502 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1503 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1504 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1505 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1506 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1507 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1508 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1509 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1510 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1511 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1512 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1513 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1514 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1515 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1516 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1517 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1518 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1519 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1520 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1521 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1522 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1523 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1524 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1525 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1526 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1527 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1528 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1529 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1530 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1531 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1532 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1533 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1534 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1535 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1536 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1537 0x00 };
1538 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1539 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1540 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1541 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1542 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1543 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1544 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1545 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1546 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1547 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1548 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1549 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1550 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1551 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1552 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1553 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1554 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1555 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1556 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1557 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1558 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1559 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1560 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1561 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1562 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1563 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1564 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1565 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1567 static void test_signed_msg_encoding(void)
1569 HCRYPTMSG msg;
1570 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1571 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1572 CERT_INFO certInfo = { 0 };
1573 CERT_BLOB encodedCert = { sizeof(cert), cert };
1574 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1575 char oid_common_name[] = szOID_COMMON_NAME;
1576 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1577 encodedCommonName };
1578 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1579 BOOL ret;
1580 HCRYPTKEY key;
1581 DWORD size;
1583 certInfo.SerialNumber.cbData = sizeof(serialNum);
1584 certInfo.SerialNumber.pbData = serialNum;
1585 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1586 certInfo.Issuer.pbData = encodedCommonName;
1587 signer.pCertInfo = &certInfo;
1588 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1589 signInfo.cSigners = 1;
1590 signInfo.rgSigners = &signer;
1592 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1593 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1594 if (!ret && GetLastError() == NTE_EXISTS) {
1595 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1596 PROV_RSA_FULL, 0);
1598 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1600 if (!ret) {
1601 skip("No context for tests\n");
1602 return;
1605 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1606 0, 0, &key);
1607 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1609 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1610 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1611 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1613 check_param("detached signed empty bare content", msg,
1614 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1615 sizeof(signedEmptyBareContent));
1616 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1617 signedEmptyContent, sizeof(signedEmptyContent));
1618 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1619 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1620 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1621 signedHash, sizeof(signedHash));
1622 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1623 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1624 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1625 detachedSignedContent, sizeof(detachedSignedContent));
1626 SetLastError(0xdeadbeef);
1627 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1628 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1629 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1630 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1631 signedEncodedSigner, sizeof(signedEncodedSigner));
1633 CryptMsgClose(msg);
1635 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1636 NULL, NULL);
1637 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1639 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1640 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1641 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1642 signedEmptyContent, sizeof(signedEmptyContent));
1643 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1644 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1645 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1646 signedBareContent, sizeof(signedBareContent));
1647 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1648 signedContent, sizeof(signedContent));
1650 CryptMsgClose(msg);
1652 signer.cAuthAttr = 1;
1653 signer.rgAuthAttr = &attr;
1654 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1655 NULL, NULL);
1656 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1658 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1659 check_param("signed with auth attrs bare content", msg,
1660 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1661 sizeof(signedWithAuthAttrsBareContent));
1663 CryptMsgClose(msg);
1665 signer.cAuthAttr = 0;
1666 signInfo.rgCertEncoded = &encodedCert;
1667 signInfo.cCertEncoded = 1;
1668 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1669 NULL, NULL);
1670 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1672 check_param("signed with cert empty bare content", msg,
1673 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1674 sizeof(signedWithCertEmptyBareContent));
1675 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1676 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1677 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1678 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1680 CryptMsgClose(msg);
1682 signInfo.cCertEncoded = 0;
1683 signInfo.rgCrlEncoded = &encodedCrl;
1684 signInfo.cCrlEncoded = 1;
1685 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1686 NULL, NULL);
1687 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1689 check_param("signed with crl empty bare content", msg,
1690 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1691 sizeof(signedWithCrlEmptyBareContent));
1692 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1693 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1694 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1695 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1697 CryptMsgClose(msg);
1699 signInfo.cCertEncoded = 1;
1700 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1701 NULL, NULL);
1702 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1704 check_param("signed with cert and crl empty bare content", msg,
1705 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1706 sizeof(signedWithCertAndCrlEmptyBareContent));
1707 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1708 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1709 check_param("signed with cert and crl bare content", msg,
1710 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1711 sizeof(signedWithCertAndCrlBareContent));
1713 CryptMsgClose(msg);
1715 /* Test with a cert with a (bogus) public key */
1716 signInfo.cCrlEncoded = 0;
1717 encodedCert.cbData = sizeof(v1CertWithPubKey);
1718 encodedCert.pbData = v1CertWithPubKey;
1719 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1720 NULL, NULL);
1721 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1722 check_param("signedWithCertWithPubKeyBareContent", msg,
1723 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1724 sizeof(signedWithCertWithPubKeyBareContent));
1725 CryptMsgClose(msg);
1727 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1728 encodedCert.pbData = v1CertWithValidPubKey;
1729 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1730 NULL, NULL);
1731 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1732 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1733 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1734 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1735 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1736 check_param("signedWithCertWithValidPubKeyContent", msg,
1737 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1738 sizeof(signedWithCertWithValidPubKeyContent));
1739 CryptMsgClose(msg);
1741 CryptDestroyKey(key);
1742 CryptReleaseContext(signer.hCryptProv, 0);
1743 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1744 CRYPT_DELETEKEYSET);
1747 static void test_signed_msg_get_param(void)
1749 BOOL ret;
1750 HCRYPTMSG msg;
1751 DWORD size, value = 0;
1752 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1753 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1754 CERT_INFO certInfo = { 0 };
1756 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1757 NULL, NULL);
1758 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1760 /* Content and bare content are always gettable */
1761 size = 0;
1762 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1763 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1764 size = 0;
1765 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1766 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1767 /* For "signed" messages, so is the version. */
1768 size = 0;
1769 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1770 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1771 size = sizeof(value);
1772 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1773 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1774 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1775 /* But for this message, with no signers, the hash and signer aren't
1776 * available.
1778 size = 0;
1779 SetLastError(0xdeadbeef);
1780 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1781 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1782 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1783 SetLastError(0xdeadbeef);
1784 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1785 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1786 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1787 /* As usual, the type isn't available. */
1788 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1789 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1790 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1792 CryptMsgClose(msg);
1794 certInfo.SerialNumber.cbData = sizeof(serialNum);
1795 certInfo.SerialNumber.pbData = serialNum;
1796 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1797 certInfo.Issuer.pbData = encodedCommonName;
1798 signer.pCertInfo = &certInfo;
1799 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1800 signInfo.cSigners = 1;
1801 signInfo.rgSigners = &signer;
1803 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1804 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1805 if (!ret && GetLastError() == NTE_EXISTS) {
1806 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1807 PROV_RSA_FULL, 0);
1809 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1811 if (!ret) {
1812 skip("No context for tests\n");
1813 return;
1816 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1817 NULL, NULL);
1818 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1820 /* This message, with one signer, has the hash and signer for index 0
1821 * available, but not for other indexes.
1823 size = 0;
1824 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1825 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1826 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1827 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1828 size = 0;
1829 SetLastError(0xdeadbeef);
1830 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1831 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1832 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1833 SetLastError(0xdeadbeef);
1834 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1835 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1836 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1837 /* As usual, the type isn't available. */
1838 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1839 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1840 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1842 CryptMsgClose(msg);
1844 CryptReleaseContext(signer.hCryptProv, 0);
1845 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1846 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1849 static void test_signed_msg(void)
1851 test_signed_msg_open();
1852 test_signed_msg_update();
1853 test_signed_msg_encoding();
1854 test_signed_msg_get_param();
1857 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1858 static const struct update_accum a4 = { 1, &b4 };
1860 static const BYTE bogusOIDContent[] = {
1861 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1862 0x04,0x00 };
1863 static const BYTE bogusHashContent[] = {
1864 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1865 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1866 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1867 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1868 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1870 static void test_decode_msg_update(void)
1872 HCRYPTMSG msg;
1873 BOOL ret;
1874 CMSG_STREAM_INFO streamInfo = { 0 };
1875 DWORD i;
1876 struct update_accum accum = { 0, NULL };
1878 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1879 /* Update with a full message in a final update */
1880 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1881 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1882 /* Can't update after a final update */
1883 SetLastError(0xdeadbeef);
1884 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1885 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1886 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1887 CryptMsgClose(msg);
1889 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1890 /* Can't send a non-final update without streaming */
1891 SetLastError(0xdeadbeef);
1892 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1893 FALSE);
1894 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1895 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1896 /* A subsequent final update succeeds */
1897 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1898 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1899 CryptMsgClose(msg);
1901 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1902 /* Updating a message that has a NULL stream callback fails */
1903 SetLastError(0xdeadbeef);
1904 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1905 FALSE);
1906 todo_wine
1907 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1908 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1909 /* Changing the callback pointer after the fact yields the same error (so
1910 * the message must copy the stream info, not just store a pointer to it)
1912 streamInfo.pfnStreamOutput = nop_stream_output;
1913 SetLastError(0xdeadbeef);
1914 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1915 FALSE);
1916 todo_wine
1917 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1918 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1919 CryptMsgClose(msg);
1921 /* Empty non-final updates are allowed when streaming.. */
1922 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1923 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1924 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1925 /* but final updates aren't when not enough data has been received. */
1926 SetLastError(0xdeadbeef);
1927 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1928 todo_wine
1929 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1930 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1931 CryptMsgClose(msg);
1933 /* Updating the message byte by byte is legal */
1934 streamInfo.pfnStreamOutput = accumulating_stream_output;
1935 streamInfo.pvArg = &accum;
1936 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1937 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1938 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1939 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1940 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1941 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1942 CryptMsgClose(msg);
1943 todo_wine
1944 check_updates("byte-by-byte empty content", &a4, &accum);
1945 free_updates(&accum);
1947 /* Decoding bogus content fails in non-streaming mode.. */
1948 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1949 SetLastError(0xdeadbeef);
1950 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1951 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1952 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1953 CryptMsgClose(msg);
1954 /* and as the final update in streaming mode.. */
1955 streamInfo.pfnStreamOutput = nop_stream_output;
1956 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1957 SetLastError(0xdeadbeef);
1958 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1959 todo_wine
1960 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1961 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1962 CryptMsgClose(msg);
1963 /* and even as a non-final update in streaming mode. */
1964 streamInfo.pfnStreamOutput = nop_stream_output;
1965 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1966 SetLastError(0xdeadbeef);
1967 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1968 todo_wine
1969 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1970 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1971 CryptMsgClose(msg);
1973 /* An empty message can be opened with undetermined type.. */
1974 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1975 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1976 TRUE);
1977 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1978 CryptMsgClose(msg);
1979 /* but decoding it as an explicitly typed message fails. */
1980 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1981 NULL);
1982 SetLastError(0xdeadbeef);
1983 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1984 TRUE);
1985 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1986 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1987 CryptMsgClose(msg);
1988 /* On the other hand, decoding the bare content of an empty message fails
1989 * with unspecified type..
1991 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1992 SetLastError(0xdeadbeef);
1993 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1994 sizeof(dataEmptyBareContent), TRUE);
1995 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1996 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1997 CryptMsgClose(msg);
1998 /* but succeeds with explicit type. */
1999 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2000 NULL);
2001 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2002 sizeof(dataEmptyBareContent), TRUE);
2003 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2004 CryptMsgClose(msg);
2006 /* Decoding valid content with an unsupported OID fails */
2007 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2008 SetLastError(0xdeadbeef);
2009 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2010 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2011 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2012 CryptMsgClose(msg);
2014 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2015 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2016 SetLastError(0xdeadbeef);
2017 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2018 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2019 CryptMsgClose(msg);
2020 /* while with specified type it fails. */
2021 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2022 NULL);
2023 SetLastError(0xdeadbeef);
2024 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2025 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2026 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2027 CryptMsgClose(msg);
2028 /* On the other hand, decoding the bare content of an empty hash message
2029 * fails with unspecified type..
2031 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2032 SetLastError(0xdeadbeef);
2033 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2034 sizeof(hashEmptyBareContent), TRUE);
2035 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2036 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2037 CryptMsgClose(msg);
2038 /* but succeeds with explicit type. */
2039 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2040 NULL);
2041 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2042 sizeof(hashEmptyBareContent), TRUE);
2043 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2044 CryptMsgClose(msg);
2046 /* And again, opening a (non-empty) hash message with unspecified type
2047 * succeeds..
2049 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2050 SetLastError(0xdeadbeef);
2051 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2052 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2053 CryptMsgClose(msg);
2054 /* while with specified type it fails.. */
2055 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2056 NULL);
2057 SetLastError(0xdeadbeef);
2058 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2059 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2060 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2061 CryptMsgClose(msg);
2062 /* and decoding the bare content of a non-empty hash message fails with
2063 * unspecified type..
2065 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2066 SetLastError(0xdeadbeef);
2067 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2068 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2069 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2070 CryptMsgClose(msg);
2071 /* but succeeds with explicit type. */
2072 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2073 NULL);
2074 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2075 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2076 CryptMsgClose(msg);
2078 /* Opening a (non-empty) hash message with unspecified type and a bogus
2079 * hash value succeeds..
2081 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2082 SetLastError(0xdeadbeef);
2083 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2084 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2085 CryptMsgClose(msg);
2087 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2088 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2089 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2090 CryptMsgClose(msg);
2091 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2092 SetLastError(0xdeadbeef);
2093 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2094 sizeof(signedWithCertAndCrlBareContent), TRUE);
2095 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2096 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2097 CryptMsgClose(msg);
2098 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2099 NULL);
2100 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2101 sizeof(signedWithCertAndCrlBareContent), TRUE);
2102 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2103 CryptMsgClose(msg);
2105 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2106 NULL, NULL);
2107 /* The first update succeeds.. */
2108 ret = CryptMsgUpdate(msg, detachedSignedContent,
2109 sizeof(detachedSignedContent), TRUE);
2110 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2111 /* as does a second (probably to update the detached portion).. */
2112 ret = CryptMsgUpdate(msg, detachedSignedContent,
2113 sizeof(detachedSignedContent), TRUE);
2114 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2115 /* while a third fails. */
2116 ret = CryptMsgUpdate(msg, detachedSignedContent,
2117 sizeof(detachedSignedContent), TRUE);
2118 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2119 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2120 CryptMsgClose(msg);
2123 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2124 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2126 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2127 const CMSG_SIGNER_INFO *expected)
2129 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2130 expected->dwVersion, got->dwVersion);
2131 ok(got->Issuer.cbData == expected->Issuer.cbData,
2132 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2133 got->Issuer.cbData);
2134 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2135 "Unexpected issuer\n");
2136 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2137 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2138 got->SerialNumber.cbData);
2139 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2140 got->SerialNumber.cbData), "Unexpected serial number\n");
2141 /* FIXME: check more things */
2144 static const BYTE signedWithCertAndCrlComputedHash[] = {
2145 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2146 0x2f };
2148 static void test_decode_msg_get_param(void)
2150 HCRYPTMSG msg;
2151 BOOL ret;
2152 DWORD size = 0, value;
2153 LPBYTE buf;
2155 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2156 SetLastError(0xdeadbeef);
2157 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2158 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2159 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2160 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2161 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2162 sizeof(msgData));
2163 CryptMsgClose(msg);
2165 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2166 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2167 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2168 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2169 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2170 emptyHashParam, sizeof(emptyHashParam));
2171 CryptMsgClose(msg);
2172 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2173 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2174 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2175 sizeof(msgData));
2176 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2177 sizeof(hashParam));
2178 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2179 hashParam, sizeof(hashParam));
2180 /* Curiously, getting the hash of index 1 succeeds, even though there's
2181 * only one hash.
2183 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2184 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2185 buf = CryptMemAlloc(size);
2186 if (buf)
2188 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2189 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2190 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2191 CryptMemFree(buf);
2193 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2194 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2195 value = CMSG_HASHED_DATA_V0;
2196 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2197 sizeof(value));
2198 CryptMsgClose(msg);
2200 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2201 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2202 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2203 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2204 sizeof(msgData));
2205 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2206 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2207 size = sizeof(value);
2208 value = 2112;
2209 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2210 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2211 ok(value == 1, "Expected 1 signer, got %d\n", value);
2212 size = 0;
2213 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2214 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2215 if (ret)
2216 buf = CryptMemAlloc(size);
2217 else
2218 buf = NULL;
2219 if (buf)
2221 CMSG_SIGNER_INFO signer = { 0 };
2223 signer.dwVersion = 1;
2224 signer.Issuer.cbData = sizeof(encodedCommonName);
2225 signer.Issuer.pbData = encodedCommonName;
2226 signer.SerialNumber.cbData = sizeof(serialNum);
2227 signer.SerialNumber.pbData = serialNum;
2228 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2229 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2230 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2231 CryptMemFree(buf);
2233 /* index is ignored when getting signer count */
2234 size = sizeof(value);
2235 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2236 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2237 ok(value == 1, "Expected 1 signer, got %d\n", value);
2238 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2239 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2240 ok(value == 0, "Expected 0 certs, got %d\n", value);
2241 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2242 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2243 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2244 CryptMsgClose(msg);
2245 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2246 NULL);
2247 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2248 sizeof(signedWithCertAndCrlBareContent), TRUE);
2249 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2250 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2251 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2252 ok(value == 1, "Expected 1 cert, got %d\n", value);
2253 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2254 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2255 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2256 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2257 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2258 check_param("signed with cert and CRL computed hash", msg,
2259 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2260 sizeof(signedWithCertAndCrlComputedHash));
2261 CryptMsgClose(msg);
2264 static void test_decode_msg(void)
2266 test_decode_msg_update();
2267 test_decode_msg_get_param();
2270 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2271 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2272 static BYTE encodedPubKey[] = {
2273 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2274 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2275 0x0d,0x0e,0x0f };
2276 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2277 static BYTE mod_encoded[] = {
2278 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2279 0x01,0x00,0x01 };
2281 static void test_msg_control(void)
2283 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2284 BOOL ret;
2285 HCRYPTMSG msg;
2286 DWORD i;
2287 CERT_INFO certInfo = { 0 };
2288 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2289 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2290 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2292 /* Crashes
2293 ret = CryptMsgControl(NULL, 0, 0, NULL);
2296 /* Data encode messages don't allow any sort of control.. */
2297 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2298 NULL);
2299 /* either with no prior update.. */
2300 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2302 SetLastError(0xdeadbeef);
2303 ret = CryptMsgControl(msg, 0, i, NULL);
2304 ok(!ret && GetLastError() == E_INVALIDARG,
2305 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2307 /* or after an update. */
2308 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2310 SetLastError(0xdeadbeef);
2311 ret = CryptMsgControl(msg, 0, i, NULL);
2312 ok(!ret && GetLastError() == E_INVALIDARG,
2313 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2315 CryptMsgClose(msg);
2317 /* Hash encode messages don't allow any sort of control.. */
2318 hashInfo.cbSize = sizeof(hashInfo);
2319 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2320 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2321 NULL, NULL);
2322 /* either with no prior update.. */
2323 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2325 SetLastError(0xdeadbeef);
2326 ret = CryptMsgControl(msg, 0, i, NULL);
2327 ok(!ret && GetLastError() == E_INVALIDARG,
2328 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2330 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2331 /* or after an update. */
2332 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2334 SetLastError(0xdeadbeef);
2335 ret = CryptMsgControl(msg, 0, i, NULL);
2336 ok(!ret && GetLastError() == E_INVALIDARG,
2337 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2339 CryptMsgClose(msg);
2341 /* Signed encode messages likewise don't allow any sort of control.. */
2342 signInfo.cbSize = sizeof(signInfo);
2343 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2344 NULL, NULL);
2345 /* either before an update.. */
2346 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2348 SetLastError(0xdeadbeef);
2349 ret = CryptMsgControl(msg, 0, i, NULL);
2350 ok(!ret && GetLastError() == E_INVALIDARG,
2351 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2353 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2354 /* or after an update. */
2355 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2357 SetLastError(0xdeadbeef);
2358 ret = CryptMsgControl(msg, 0, i, NULL);
2359 ok(!ret && GetLastError() == E_INVALIDARG,
2360 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2362 CryptMsgClose(msg);
2364 /* Decode messages behave a bit differently. */
2365 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2366 /* Bad control type */
2367 SetLastError(0xdeadbeef);
2368 ret = CryptMsgControl(msg, 0, 0, NULL);
2369 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2370 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2371 SetLastError(0xdeadbeef);
2372 ret = CryptMsgControl(msg, 1, 0, NULL);
2373 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2374 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2375 /* Can't verify the hash of an indeterminate-type message */
2376 SetLastError(0xdeadbeef);
2377 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2378 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2379 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2380 /* Crashes
2381 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2383 /* Can't decrypt an indeterminate-type message */
2384 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2385 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2386 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2387 CryptMsgClose(msg);
2389 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2390 NULL);
2391 /* Can't verify the hash of an empty message */
2392 SetLastError(0xdeadbeef);
2393 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2394 todo_wine
2395 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2396 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2397 /* Crashes
2398 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2400 /* Can't verify the signature of a hash message */
2401 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2402 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2403 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2404 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2405 TRUE);
2406 /* Oddly enough, this fails */
2407 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2408 todo_wine
2409 ok(!ret, "Expected failure\n");
2410 CryptMsgClose(msg);
2411 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2412 NULL);
2413 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2414 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2415 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2416 /* Can't decrypt an indeterminate-type message */
2417 SetLastError(0xdeadbeef);
2418 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2419 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2420 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2421 CryptMsgClose(msg);
2423 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2424 NULL);
2425 /* Can't verify the hash of a signed message */
2426 SetLastError(0xdeadbeef);
2427 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2428 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2429 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2430 /* Can't decrypt a signed message */
2431 SetLastError(0xdeadbeef);
2432 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2433 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2434 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2435 /* Crash
2436 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2437 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2439 CryptMsgUpdate(msg, signedWithCertBareContent,
2440 sizeof(signedWithCertBareContent), TRUE);
2441 /* With an empty cert info, the signer can't be found in the message (and
2442 * the signature can't be verified.
2444 SetLastError(0xdeadbeef);
2445 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2446 ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2447 "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2448 /* The cert info is expected to have an issuer, serial number, and public
2449 * key info set.
2451 certInfo.SerialNumber.cbData = sizeof(serialNum);
2452 certInfo.SerialNumber.pbData = serialNum;
2453 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2454 certInfo.Issuer.pbData = encodedCommonName;
2455 SetLastError(0xdeadbeef);
2456 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2457 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2458 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2459 CryptMsgClose(msg);
2460 /* This cert has a public key, but it's not in a usable form */
2461 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2462 NULL);
2463 CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2464 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2465 /* Again, cert info needs to have a public key set */
2466 SetLastError(0xdeadbeef);
2467 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2468 ok(!ret &&
2469 (GetLastError() == CRYPT_E_ASN1_EOD ||
2470 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2471 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2472 /* The public key is supposed to be in encoded form.. */
2473 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2474 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2475 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2476 SetLastError(0xdeadbeef);
2477 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2478 ok(!ret &&
2479 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2480 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2481 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2482 /* but not as a X509_PUBLIC_KEY_INFO.. */
2483 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2484 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2485 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2486 SetLastError(0xdeadbeef);
2487 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2488 ok(!ret &&
2489 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2490 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2491 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2492 /* This decodes successfully, but it doesn't match any key in the message */
2493 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2494 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2495 SetLastError(0xdeadbeef);
2496 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2497 /* In Wine's rsaenh, this fails to decode because the key length is too
2498 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
2499 * now.
2501 todo_wine
2502 ok(!ret &&
2503 (GetLastError() == NTE_BAD_SIGNATURE ||
2504 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2505 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2506 CryptMsgClose(msg);
2507 /* A message with no data doesn't have a valid signature */
2508 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2509 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2510 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2511 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2512 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2513 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2514 SetLastError(0xdeadbeef);
2515 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2516 ok(!ret &&
2517 (GetLastError() == NTE_BAD_SIGNATURE ||
2518 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2519 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2520 CryptMsgClose(msg);
2521 /* Finally, this succeeds */
2522 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2523 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2524 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2525 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2526 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2527 CryptMsgClose(msg);
2530 /* win9x has much less parameter checks and will crash on many tests
2531 * this code is from test_signed_msg_update()
2533 static BOOL detect_nt(void)
2535 BOOL ret;
2536 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
2537 CERT_INFO certInfo = { 0 };
2540 certInfo.SerialNumber.cbData = sizeof(serialNum);
2541 certInfo.SerialNumber.pbData = serialNum;
2542 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2543 certInfo.Issuer.pbData = encodedCommonName;
2544 signer.pCertInfo = &certInfo;
2545 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2547 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2548 PROV_RSA_FULL, CRYPT_NEWKEYSET);
2549 if (!ret && GetLastError() == NTE_EXISTS) {
2550 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2551 PROV_RSA_FULL, 0);
2554 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
2556 /* cleanup */
2557 CryptReleaseContext(signer.hCryptProv, 0);
2558 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
2559 CRYPT_DELETEKEYSET);
2561 return TRUE;
2564 static void test_msg_get_and_verify_signer(void)
2566 BOOL ret;
2567 HCRYPTMSG msg;
2568 PCCERT_CONTEXT signer;
2569 DWORD signerIndex;
2570 HCERTSTORE store;
2572 /* Crash */
2573 if (0)
2575 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
2576 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
2579 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2580 /* An empty message has no signer */
2581 SetLastError(0xdeadbeef);
2582 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2583 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2584 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2585 /* The signer is cleared on error */
2586 signer = (PCCERT_CONTEXT)0xdeadbeef;
2587 SetLastError(0xdeadbeef);
2588 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2589 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2590 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2591 ok(!signer, "expected signer to be NULL\n");
2592 /* The signer index is also cleared on error */
2593 signerIndex = 0xdeadbeef;
2594 SetLastError(0xdeadbeef);
2595 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2596 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2597 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2598 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
2599 /* An unsigned message (msgData isn't a signed message at all)
2600 * likewise has no signer.
2602 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2603 SetLastError(0xdeadbeef);
2604 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2605 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2606 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2607 CryptMsgClose(msg);
2609 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2610 /* A "signed" message created with no signer cert likewise has no signer */
2611 CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
2612 SetLastError(0xdeadbeef);
2613 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2614 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2615 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2616 CryptMsgClose(msg);
2618 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2619 /* A signed message succeeds, .. */
2620 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2621 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2622 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2623 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2624 /* the signer index can be retrieved, .. */
2625 signerIndex = 0xdeadbeef;
2626 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2627 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2628 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
2629 /* as can the signer cert. */
2630 signer = (PCCERT_CONTEXT)0xdeadbeef;
2631 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2632 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2633 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
2634 "expected a valid signer\n");
2635 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
2636 CertFreeCertificateContext(signer);
2637 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
2639 signerIndex = 0xdeadbeef;
2640 SetLastError(0xdeadbeef);
2641 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
2642 NULL, &signerIndex);
2643 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
2644 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
2645 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
2646 * message signer not to be found.
2648 SetLastError(0xdeadbeef);
2649 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
2650 NULL, NULL);
2651 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2652 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2653 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
2654 * the message signer not to be found.
2656 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
2657 CERT_STORE_CREATE_NEW_FLAG, NULL);
2658 SetLastError(0xdeadbeef);
2659 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
2660 NULL, NULL);
2661 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2662 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2663 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
2664 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
2665 CERT_STORE_ADD_ALWAYS, NULL);
2666 ok(ret, "CertAddEncodedCertificateToStore failed: 0x%08x\n",
2667 GetLastError());
2668 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
2669 * the signer succeeds.
2671 SetLastError(0xdeadbeef);
2672 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
2673 NULL, NULL);
2674 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2675 CertCloseStore(store, 0);
2676 CryptMsgClose(msg);
2679 START_TEST(msg)
2681 init_function_pointers();
2682 have_nt = detect_nt();
2684 /* Basic parameter checking tests */
2685 test_msg_open_to_encode();
2686 test_msg_open_to_decode();
2687 test_msg_get_param();
2688 test_msg_close();
2689 test_msg_control();
2691 /* Message-type specific tests */
2692 test_data_msg();
2693 test_hash_msg();
2694 test_signed_msg();
2695 test_decode_msg();
2697 test_msg_get_and_verify_signer();