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