po: Update Korean resource.
[wine.git] / dlls / crypt32 / tests / msg.c
blobd5d5309c8283d74309665421d4d87d7a72f8e9b4
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 const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
370 static void test_data_msg_update(void)
372 HCRYPTMSG msg;
373 BOOL ret;
374 CMSG_STREAM_INFO streamInfo = { 0 };
376 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
377 NULL);
378 /* Can't update a message that wasn't opened detached with final = FALSE */
379 SetLastError(0xdeadbeef);
380 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
381 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
382 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
383 /* Updating it with final = TRUE succeeds */
384 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
385 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
386 /* Any subsequent update will fail, as the last was final */
387 SetLastError(0xdeadbeef);
388 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
389 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
390 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
391 CryptMsgClose(msg);
393 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
394 NULL);
395 /* Starting with Vista, can update a message with no data. */
396 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
397 ok(ret || broken(!ret), "CryptMsgUpdate failed: %08x\n", GetLastError());
398 if (ret)
400 DWORD size;
402 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
403 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
404 if (ret)
406 LPBYTE buf = CryptMemAlloc(size);
408 if (buf)
410 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, buf,
411 &size);
412 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
413 if (ret)
415 ok(size == sizeof(dataEmptyBareContent),
416 "unexpected size %d\n", size);
417 ok(!memcmp(buf, dataEmptyBareContent, size),
418 "unexpected value\n");
420 CryptMemFree(buf);
424 CryptMsgClose(msg);
426 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
427 CMSG_DATA, NULL, NULL, NULL);
428 if (have_nt)
430 /* Doesn't appear to be able to update CMSG-DATA with non-final updates.
431 * On Win9x, this sometimes succeeds, sometimes fails with
432 * GetLastError() == 0, so it's not worth checking there.
434 SetLastError(0xdeadbeef);
435 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
436 ok(!ret &&
437 (GetLastError() == E_INVALIDARG ||
438 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
439 "Expected E_INVALIDARG, got %x\n", GetLastError());
440 SetLastError(0xdeadbeef);
441 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
442 ok(!ret &&
443 (GetLastError() == E_INVALIDARG ||
444 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
445 "Expected E_INVALIDARG, got %x\n", GetLastError());
447 else
448 skip("not updating CMSG_DATA with a non-final update\n");
449 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
450 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
451 CryptMsgClose(msg);
453 if (!old_crypt32)
455 /* Calling update after opening with an empty stream info (with a bogus
456 * output function) yields an error:
458 /* Crashes on some Win9x */
459 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
460 &streamInfo);
461 SetLastError(0xdeadbeef);
462 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
463 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
464 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
465 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
466 GetLastError());
467 CryptMsgClose(msg);
469 /* Calling update with a valid output function succeeds, even if the data
470 * exceeds the size specified in the stream info.
472 streamInfo.pfnStreamOutput = nop_stream_output;
473 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
474 &streamInfo);
475 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
476 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
477 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
478 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
479 CryptMsgClose(msg);
482 static void test_data_msg_get_param(void)
484 HCRYPTMSG msg;
485 DWORD size;
486 BOOL ret;
487 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
489 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
490 NULL);
492 /* Content and bare content are always gettable when not streaming */
493 size = 0;
494 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
495 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
496 size = 0;
497 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
498 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
499 /* But for this type of message, the signer and hash aren't applicable,
500 * and the type isn't available.
502 size = 0;
503 SetLastError(0xdeadbeef);
504 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
505 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
506 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
507 SetLastError(0xdeadbeef);
508 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
509 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
510 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
511 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
512 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
513 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
514 CryptMsgClose(msg);
516 /* Can't get content or bare content when streaming */
517 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
518 NULL, &streamInfo);
519 SetLastError(0xdeadbeef);
520 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
521 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
522 "Expected E_INVALIDARG, got %x\n", GetLastError());
523 SetLastError(0xdeadbeef);
524 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
525 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
526 "Expected E_INVALIDARG, got %x\n", GetLastError());
527 CryptMsgClose(msg);
530 static const BYTE dataEmptyContent[] = {
531 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
532 0x04,0x00 };
533 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
534 static const BYTE dataContent[] = {
535 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
536 0x04,0x04,0x01,0x02,0x03,0x04 };
538 struct update_accum
540 DWORD cUpdates;
541 CRYPT_DATA_BLOB *updates;
544 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
545 DWORD cb, BOOL final)
547 struct update_accum *accum = (struct update_accum *)pvArg;
548 BOOL ret = FALSE;
550 if (accum->cUpdates)
551 accum->updates = CryptMemRealloc(accum->updates,
552 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
553 else
554 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
555 if (accum->updates)
557 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
559 blob->pbData = CryptMemAlloc(cb);
560 if (blob->pbData)
562 memcpy(blob->pbData, pb, cb);
563 blob->cbData = cb;
564 ret = TRUE;
566 accum->cUpdates++;
568 return ret;
571 /* The updates of a (bogus) definite-length encoded message */
572 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
573 0x07,0x01,0xa0,0x02,0x04,0x00 };
574 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
575 static CRYPT_DATA_BLOB b1[] = {
576 { sizeof(u1), u1 },
577 { sizeof(u2), u2 },
578 { sizeof(u2), u2 },
580 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
581 /* The updates of a definite-length encoded message */
582 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
583 0x07,0x01,0xa0,0x06,0x04,0x04 };
584 static CRYPT_DATA_BLOB b2[] = {
585 { sizeof(u3), u3 },
586 { sizeof(u2), u2 },
588 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
589 /* The updates of an indefinite-length encoded message */
590 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
591 0x07,0x01,0xa0,0x80,0x24,0x80 };
592 static BYTE u5[] = { 0x04,0x04 };
593 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
594 static CRYPT_DATA_BLOB b3[] = {
595 { sizeof(u4), u4 },
596 { sizeof(u5), u5 },
597 { sizeof(u2), u2 },
598 { sizeof(u5), u5 },
599 { sizeof(u2), u2 },
600 { sizeof(u6), u6 },
602 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
604 static void check_updates(LPCSTR header, const struct update_accum *expected,
605 const struct update_accum *got)
607 DWORD i;
609 ok(expected->cUpdates == got->cUpdates,
610 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
611 got->cUpdates);
612 if (expected->cUpdates == got->cUpdates)
613 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
615 ok(expected->updates[i].cbData == got->updates[i].cbData,
616 "%s, update %d: expected %d bytes, got %d\n", header, i,
617 expected->updates[i].cbData, got->updates[i].cbData);
618 if (expected->updates[i].cbData && expected->updates[i].cbData ==
619 got->updates[i].cbData)
620 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
621 got->updates[i].cbData), "%s, update %d: unexpected value\n",
622 header, i);
626 /* Frees the updates stored in accum */
627 static void free_updates(struct update_accum *accum)
629 DWORD i;
631 for (i = 0; i < accum->cUpdates; i++)
632 CryptMemFree(accum->updates[i].pbData);
633 CryptMemFree(accum->updates);
634 accum->updates = NULL;
635 accum->cUpdates = 0;
638 static void test_data_msg_encoding(void)
640 HCRYPTMSG msg;
641 BOOL ret;
642 static char oid[] = "1.2.3";
643 struct update_accum accum = { 0, NULL };
644 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
646 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
647 NULL);
648 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
649 dataEmptyBareContent, sizeof(dataEmptyBareContent));
650 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
651 sizeof(dataEmptyContent));
652 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
653 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
654 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
655 dataBareContent, sizeof(dataBareContent));
656 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
657 sizeof(dataContent));
658 CryptMsgClose(msg);
659 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
660 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
661 CMSG_DATA, NULL, NULL, NULL);
662 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
663 dataEmptyBareContent, sizeof(dataEmptyBareContent));
664 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
665 sizeof(dataEmptyContent));
666 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
667 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
668 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
669 dataBareContent, sizeof(dataBareContent));
670 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
671 sizeof(dataContent));
672 CryptMsgClose(msg);
673 /* The inner OID is apparently ignored */
674 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
675 NULL);
676 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
677 dataEmptyBareContent, sizeof(dataEmptyBareContent));
678 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
679 dataEmptyContent, sizeof(dataEmptyContent));
680 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
681 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
682 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
683 dataBareContent, sizeof(dataBareContent));
684 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
685 sizeof(dataContent));
686 CryptMsgClose(msg);
687 /* A streaming message is DER encoded if the length is not 0xffffffff, but
688 * curiously, updates aren't validated to make sure they don't exceed the
689 * stated length. (The resulting output will of course fail to decode.)
691 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
692 NULL, &streamInfo);
693 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
694 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
695 CryptMsgClose(msg);
696 check_updates("bogus data message with definite length", &a1, &accum);
697 free_updates(&accum);
698 /* A valid definite-length encoding: */
699 streamInfo.cbContent = sizeof(msgData);
700 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
701 NULL, &streamInfo);
702 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
703 CryptMsgClose(msg);
704 check_updates("data message with definite length", &a2, &accum);
705 free_updates(&accum);
706 /* An indefinite-length encoding: */
707 streamInfo.cbContent = 0xffffffff;
708 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
709 NULL, &streamInfo);
710 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
711 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
712 CryptMsgClose(msg);
713 check_updates("data message with indefinite length", &a3, &accum);
714 free_updates(&accum);
717 static void test_data_msg(void)
719 test_data_msg_open();
720 test_data_msg_update();
721 test_data_msg_get_param();
722 test_data_msg_encoding();
725 static void test_hash_msg_open(void)
727 HCRYPTMSG msg;
728 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
729 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
731 SetLastError(0xdeadbeef);
732 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
733 NULL, NULL);
734 ok(!msg && GetLastError() == E_INVALIDARG,
735 "Expected E_INVALIDARG, got %x\n", GetLastError());
736 hashInfo.cbSize = sizeof(hashInfo);
737 SetLastError(0xdeadbeef);
738 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
739 NULL, NULL);
740 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
741 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
742 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
743 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
744 NULL, NULL);
745 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
746 CryptMsgClose(msg);
747 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
748 CMSG_HASHED, &hashInfo, NULL, NULL);
749 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
750 CryptMsgClose(msg);
751 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
752 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
753 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
754 CryptMsgClose(msg);
757 static void test_hash_msg_update(void)
759 HCRYPTMSG msg;
760 BOOL ret;
761 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
762 { oid_rsa_md5, { 0, NULL } }, NULL };
763 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
765 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
766 CMSG_HASHED, &hashInfo, NULL, NULL);
767 /* Detached hashed messages opened in non-streaming mode allow non-final
768 * updates..
770 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
771 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
772 /* including non-final updates with no data.. */
773 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
774 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
775 /* and final updates with no data. */
776 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
777 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
778 /* But no updates are allowed after the final update. */
779 SetLastError(0xdeadbeef);
780 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
781 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
782 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
783 SetLastError(0xdeadbeef);
784 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
785 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
786 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
787 CryptMsgClose(msg);
788 /* Non-detached messages, in contrast, don't allow non-final updates in
789 * non-streaming mode.
791 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
792 NULL, NULL);
793 SetLastError(0xdeadbeef);
794 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
795 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
796 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
797 /* Final updates (including empty ones) are allowed. */
798 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
799 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
800 CryptMsgClose(msg);
801 /* And, of course, streaming mode allows non-final updates */
802 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
803 NULL, &streamInfo);
804 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
805 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
806 CryptMsgClose(msg);
807 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
808 * to be a bug, it isn't actually used - see encoding tests.)
810 streamInfo.pfnStreamOutput = NULL;
811 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
812 NULL, &streamInfo);
813 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
814 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
815 CryptMsgClose(msg);
818 static const BYTE emptyHashParam[] = {
819 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
820 0x7e };
822 static void test_hash_msg_get_param(void)
824 HCRYPTMSG msg;
825 BOOL ret;
826 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
827 { oid_rsa_md5, { 0, NULL } }, NULL };
828 DWORD size, value;
829 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
830 BYTE buf[16];
832 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
833 NULL, NULL);
834 /* Content and bare content are always gettable for non-streamed messages */
835 size = 0;
836 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
837 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
838 "CryptMsgGetParam failed: %08x\n", GetLastError());
839 size = 0;
840 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
841 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
842 "CryptMsgGetParam failed: %08x\n", GetLastError());
843 /* For an encoded hash message, the hash data aren't available */
844 SetLastError(0xdeadbeef);
845 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
846 ok(!ret && (GetLastError() == CRYPT_E_INVALID_MSG_TYPE ||
847 GetLastError() == OSS_LIMITED /* Win9x */),
848 "Expected CRYPT_E_INVALID_MSG_TYPE or OSS_LIMITED, got %08x\n",
849 GetLastError());
850 /* The hash is also available. */
851 size = 0;
852 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
853 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
854 ok(size == sizeof(buf), "Unexpected size %d\n", size);
855 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
856 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
857 ok(size == sizeof(buf), "Unexpected size %d\n", size);
858 if (size == sizeof(buf))
859 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
860 /* By getting the hash, further updates are not allowed */
861 SetLastError(0xdeadbeef);
862 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
863 ok(!ret &&
864 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
865 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
866 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
867 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
868 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
870 /* Even after a final update, the hash data aren't available */
871 SetLastError(0xdeadbeef);
872 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
873 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
874 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
875 /* The version is also available, and should be zero for this message. */
876 size = 0;
877 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
878 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
879 "CryptMsgGetParam failed: %08x\n", GetLastError());
880 size = sizeof(value);
881 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
882 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
883 "CryptMsgGetParam failed: %08x\n", GetLastError());
884 if (ret)
885 ok(value == 0, "Expected version 0, got %d\n", value);
886 /* As usual, the type isn't available. */
887 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
888 ok(!ret, "Expected failure\n");
889 CryptMsgClose(msg);
891 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
892 NULL, &streamInfo);
893 /* Streamed messages don't allow you to get the content or bare content. */
894 SetLastError(0xdeadbeef);
895 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
896 ok(!ret && (GetLastError() == E_INVALIDARG ||
897 GetLastError() == OSS_LIMITED /* Win9x */),
898 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
899 SetLastError(0xdeadbeef);
900 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
901 ok(!ret && (GetLastError() == E_INVALIDARG ||
902 GetLastError() == OSS_LIMITED /* Win9x */),
903 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
904 /* The hash is still available. */
905 size = 0;
906 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
907 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
908 ok(size == sizeof(buf), "Unexpected size %d\n", size);
909 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
910 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
911 if (size == sizeof(buf))
912 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
913 /* After updating the hash, further updates aren't allowed on streamed
914 * messages either.
916 SetLastError(0xdeadbeef);
917 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
918 ok(!ret &&
919 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
920 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
921 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
922 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
923 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
925 CryptMsgClose(msg);
928 static const BYTE hashEmptyBareContent[] = {
929 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
930 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
931 static const BYTE hashEmptyContent[] = {
932 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
933 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
934 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
935 static const BYTE hashBareContent[] = {
936 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
937 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
938 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
939 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
940 static const BYTE hashContent[] = {
941 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
942 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
943 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
944 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
945 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
947 static const BYTE detachedHashNonFinalBareContent[] = {
948 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
949 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
950 0x07,0x01,0x04,0x00 };
951 static const BYTE detachedHashNonFinalContent[] = {
952 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
953 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
954 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
955 0x07,0x01,0x04,0x00 };
956 static const BYTE detachedHashBareContent[] = {
957 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
958 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
959 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
960 0x9d,0x2a,0x8f,0x26,0x2f };
961 static const BYTE detachedHashContent[] = {
962 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
963 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
964 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
965 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
966 0x9d,0x2a,0x8f,0x26,0x2f };
968 static void test_hash_msg_encoding(void)
970 HCRYPTMSG msg;
971 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
972 BOOL ret;
973 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
974 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
976 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
977 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
978 NULL, NULL);
979 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
980 hashEmptyBareContent, sizeof(hashEmptyBareContent));
981 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
982 hashEmptyContent, sizeof(hashEmptyContent));
983 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
984 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
985 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
986 hashBareContent, sizeof(hashBareContent));
987 check_param("hash content", msg, CMSG_CONTENT_PARAM,
988 hashContent, sizeof(hashContent));
989 CryptMsgClose(msg);
990 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
991 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
992 CMSG_HASHED, &hashInfo, NULL, NULL);
993 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
994 hashEmptyBareContent, sizeof(hashEmptyBareContent));
995 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
996 hashEmptyContent, sizeof(hashEmptyContent));
997 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
998 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
999 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1000 hashBareContent, sizeof(hashBareContent));
1001 check_param("hash content", msg, CMSG_CONTENT_PARAM,
1002 hashContent, sizeof(hashContent));
1003 CryptMsgClose(msg);
1004 /* Same test, but with CMSG_DETACHED_FLAG set */
1005 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
1006 CMSG_HASHED, &hashInfo, NULL, NULL);
1007 check_param("detached hash empty bare content", msg,
1008 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
1009 sizeof(hashEmptyBareContent));
1010 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
1011 hashEmptyContent, sizeof(hashEmptyContent));
1012 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1013 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1014 check_param("detached hash not final bare content", msg,
1015 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
1016 sizeof(detachedHashNonFinalBareContent));
1017 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
1018 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
1019 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1020 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1021 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1022 detachedHashBareContent, sizeof(detachedHashBareContent));
1023 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1024 detachedHashContent, sizeof(detachedHashContent));
1025 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1026 detachedHashBareContent, sizeof(detachedHashBareContent));
1027 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1028 detachedHashContent, sizeof(detachedHashContent));
1029 CryptMsgClose(msg);
1030 /* In what appears to be a bug, streamed updates to hash messages don't
1031 * call the output function.
1033 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
1034 NULL, &streamInfo);
1035 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1036 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1037 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1038 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1039 CryptMsgClose(msg);
1040 check_updates("empty hash message", &empty_accum, &accum);
1041 free_updates(&accum);
1043 streamInfo.cbContent = sizeof(msgData);
1044 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
1045 NULL, &streamInfo);
1046 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1047 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1048 CryptMsgClose(msg);
1049 check_updates("hash message", &empty_accum, &accum);
1050 free_updates(&accum);
1052 streamInfo.cbContent = sizeof(msgData);
1053 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
1054 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
1055 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1056 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1057 CryptMsgClose(msg);
1058 check_updates("detached hash message", &empty_accum, &accum);
1059 free_updates(&accum);
1062 static void test_hash_msg(void)
1064 test_hash_msg_open();
1065 test_hash_msg_update();
1066 test_hash_msg_get_param();
1067 test_hash_msg_encoding();
1070 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1071 'm','p',0 };
1072 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1073 'm','p',0 };
1074 static BYTE serialNum[] = { 1 };
1075 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1076 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1078 static void test_signed_msg_open(void)
1080 HCRYPTMSG msg;
1081 BOOL ret;
1082 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1083 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1084 CERT_INFO certInfo = { 0 };
1086 SetLastError(0xdeadbeef);
1087 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1088 NULL, NULL);
1089 ok(!msg && GetLastError() == E_INVALIDARG,
1090 "Expected E_INVALIDARG, got %x\n", GetLastError());
1091 signInfo.cbSize = sizeof(signInfo);
1092 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1093 NULL, NULL);
1094 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1095 CryptMsgClose(msg);
1097 signInfo.cSigners = 1;
1098 signInfo.rgSigners = &signer;
1099 /* With signer.pCertInfo unset, attempting to open this message this
1100 * crashes.
1102 signer.pCertInfo = &certInfo;
1103 /* The cert info must contain a serial number and an issuer. */
1104 SetLastError(0xdeadbeef);
1105 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1106 NULL, NULL);
1107 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1108 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1109 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1110 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1111 GetLastError());
1113 certInfo.SerialNumber.cbData = sizeof(serialNum);
1114 certInfo.SerialNumber.pbData = serialNum;
1115 SetLastError(0xdeadbeef);
1116 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1117 NULL, NULL);
1118 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1119 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1120 || GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1121 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1122 GetLastError());
1124 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1125 certInfo.Issuer.pbData = encodedCommonName;
1126 SetLastError(0xdeadbeef);
1127 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1128 NULL, NULL);
1129 ok(!msg && (GetLastError() == E_INVALIDARG ||
1130 GetLastError() == CRYPT_E_UNKNOWN_ALGO),
1131 "Expected E_INVALIDARG or CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1133 /* The signer's hCryptProv must be set to something. Whether it's usable
1134 * or not will be checked after the hash algorithm is checked (see next
1135 * test.)
1137 signer.hCryptProv = 1;
1138 SetLastError(0xdeadbeef);
1139 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1140 NULL, NULL);
1141 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1142 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1143 /* The signer's hash algorithm must also be set. */
1144 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1145 SetLastError(0xdeadbeef);
1146 /* Crashes in advapi32 in wine, don't do it */
1147 if (0) {
1148 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1149 &signInfo, NULL, NULL);
1150 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1151 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1153 /* The signer's hCryptProv must also be valid. */
1154 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1155 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1156 if (!ret && GetLastError() == NTE_EXISTS) {
1157 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1158 PROV_RSA_FULL, 0);
1160 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1162 if (ret) {
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);
1169 /* pCertInfo must still be set, but can be empty if the SignerId's issuer
1170 * and serial number are set.
1172 certInfo.Issuer.cbData = 0;
1173 certInfo.SerialNumber.cbData = 0;
1174 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1175 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1176 sizeof(encodedCommonName);
1177 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1178 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1179 sizeof(serialNum);
1180 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1181 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1182 NULL, NULL);
1183 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1184 CryptMsgClose(msg);
1186 CryptReleaseContext(signer.hCryptProv, 0);
1187 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1188 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1191 static const BYTE privKey[] = {
1192 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1193 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1194 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1195 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1196 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1197 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1198 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1199 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1200 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1201 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1202 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1203 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1204 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1205 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1206 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1207 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1208 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1209 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1210 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1211 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1212 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1213 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1214 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1215 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1216 static BYTE pubKey[] = {
1217 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1218 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1219 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1220 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1221 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1223 static void test_signed_msg_update(void)
1225 HCRYPTMSG msg;
1226 BOOL ret;
1227 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1228 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1229 CERT_INFO certInfo = { 0 };
1230 HCRYPTKEY key;
1232 certInfo.SerialNumber.cbData = sizeof(serialNum);
1233 certInfo.SerialNumber.pbData = serialNum;
1234 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1235 certInfo.Issuer.pbData = encodedCommonName;
1236 signer.pCertInfo = &certInfo;
1237 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1238 signInfo.cSigners = 1;
1239 signInfo.rgSigners = &signer;
1241 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1242 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1243 if (!ret && GetLastError() == NTE_EXISTS) {
1244 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1245 PROV_RSA_FULL, 0);
1247 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1249 if (!ret) {
1250 skip("No context for tests\n");
1251 return;
1254 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1255 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1256 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1257 /* Detached CMSG_SIGNED allows non-final updates. */
1258 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1259 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1260 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1261 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1262 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1263 /* The final update requires a private key in the hCryptProv, in order to
1264 * generate the signature.
1266 SetLastError(0xdeadbeef);
1267 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1268 ok(!ret &&
1269 (GetLastError() == NTE_BAD_KEYSET ||
1270 GetLastError() == NTE_NO_KEY ||
1271 broken(GetLastError() == ERROR_SUCCESS)), /* Some Win9x */
1272 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1273 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1274 0, 0, &key);
1275 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1276 /* The final update should be able to succeed now that a key exists, but
1277 * the previous (invalid) final update prevents it.
1279 SetLastError(0xdeadbeef);
1280 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1281 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1282 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1283 CryptMsgClose(msg);
1285 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1286 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1287 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1288 /* Detached CMSG_SIGNED allows non-final updates. */
1289 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1290 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1291 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1292 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1293 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1294 /* Now that the private key exists, the final update can succeed (even
1295 * with no data.)
1297 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1298 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1299 /* But no updates are allowed after the final update. */
1300 SetLastError(0xdeadbeef);
1301 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1302 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1303 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1304 SetLastError(0xdeadbeef);
1305 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1306 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1307 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1308 CryptMsgClose(msg);
1310 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1311 NULL, NULL);
1312 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1313 /* Non-detached messages don't allow non-final updates.. */
1314 SetLastError(0xdeadbeef);
1315 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1316 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1317 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1318 /* but they do allow final ones. */
1319 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1320 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1321 CryptMsgClose(msg);
1322 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1323 NULL, NULL);
1324 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1325 /* They also allow final updates with no data. */
1326 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1327 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1328 CryptMsgClose(msg);
1330 CryptDestroyKey(key);
1331 CryptReleaseContext(signer.hCryptProv, 0);
1332 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1333 CRYPT_DELETEKEYSET);
1336 static const BYTE signedEmptyBareContent[] = {
1337 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1338 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1339 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1340 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1341 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1342 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1343 static const BYTE signedEmptyContent[] = {
1344 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1345 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1346 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1347 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1348 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1349 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1350 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1351 static const BYTE detachedSignedBareContent[] = {
1352 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1353 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1354 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1355 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1356 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1357 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1358 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1359 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1360 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1361 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1362 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1363 static const BYTE detachedSignedContent[] = {
1364 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1365 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1366 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1367 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1368 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1369 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1370 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1371 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1372 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1373 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1374 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1375 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1376 static const BYTE signedBareContent[] = {
1377 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1378 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1379 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1380 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1381 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1382 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1383 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1384 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1385 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1386 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1387 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1388 static const BYTE signedContent[] = {
1389 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1390 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1391 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1392 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1393 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1394 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1395 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1396 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1397 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1398 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1399 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1400 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1401 0x0d };
1402 static const BYTE signedHash[] = {
1403 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1404 0x2f };
1405 static const BYTE signedKeyIdEmptyContent[] = {
1406 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
1407 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1408 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
1409 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1410 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1411 static const BYTE signedEncodedSigner[] = {
1412 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1413 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1414 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1415 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1416 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1417 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1418 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1419 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1420 static const BYTE signedWithAuthAttrsBareContent[] = {
1421 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1422 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1423 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1424 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1425 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1426 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1427 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1428 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1429 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1430 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1431 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1432 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1433 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1434 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1435 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1436 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1437 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1438 0xff,0xc6,0x33,0x63,0x34 };
1439 static BYTE cert[] = {
1440 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1441 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1442 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1443 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1444 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1445 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1446 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1447 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1448 0xff,0x02,0x01,0x01 };
1449 static BYTE v1CertWithPubKey[] = {
1450 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1451 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1452 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1453 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1454 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1455 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1456 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1457 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1458 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1459 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1460 0x01,0x01 };
1461 static const BYTE signedWithCertEmptyBareContent[] = {
1462 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1463 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1464 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1465 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1466 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1467 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1468 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1469 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1470 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1471 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1472 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1473 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1474 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1475 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1476 static const BYTE signedWithCertBareContent[] = {
1477 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1478 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1479 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1480 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1481 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1482 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1483 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1484 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1485 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1486 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1487 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1488 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1489 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1490 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1491 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1492 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1493 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1494 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1495 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1496 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1497 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1498 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1499 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1500 0x30,0x30,0x30,0x30,0x5a };
1501 static const BYTE signedWithCrlEmptyBareContent[] = {
1502 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1503 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1504 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1505 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1506 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1507 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1508 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1509 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1510 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1511 static const BYTE signedWithCrlBareContent[] = {
1512 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1513 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1514 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1515 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1516 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1517 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1518 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1519 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1520 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1521 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1522 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1523 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1524 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1525 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1526 0xa8,0x0d };
1527 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1528 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1529 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1530 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1531 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1532 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1533 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1534 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1535 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1536 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1537 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1538 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1539 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1540 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1541 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1542 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1543 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1544 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1545 0x04,0x00 };
1546 static const BYTE signedWithCertAndCrlBareContent[] = {
1547 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1548 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1549 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1550 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1551 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1552 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1553 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1554 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1555 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1556 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1557 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1558 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1559 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1560 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1561 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1562 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1563 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1564 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1565 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1566 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1567 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1568 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1569 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1570 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1571 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1572 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1573 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1574 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1575 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1576 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1577 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1578 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1579 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1580 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1581 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1582 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1583 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1584 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1585 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1586 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1587 static BYTE v1CertWithValidPubKey[] = {
1588 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1589 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1590 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1591 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1592 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1593 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1594 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1595 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1596 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1597 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1598 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1599 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1600 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1601 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1602 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1603 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1604 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1605 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1606 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1607 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1608 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1609 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1610 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1611 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1612 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1613 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1614 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1615 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1616 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1617 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1618 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1619 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1620 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1621 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1622 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1623 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1624 0x00 };
1625 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1626 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1627 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1628 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1629 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1630 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1631 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1632 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1633 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1634 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1635 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1636 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1637 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1638 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1639 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1640 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1641 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1642 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1643 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1644 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1645 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1646 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1647 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1648 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1649 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1650 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1651 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1652 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1654 static void test_signed_msg_encoding(void)
1656 HCRYPTMSG msg;
1657 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1658 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1659 CERT_INFO certInfo = { 0 };
1660 CERT_BLOB encodedCert = { sizeof(cert), cert };
1661 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1662 char oid_common_name[] = szOID_COMMON_NAME;
1663 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1664 encodedCommonName };
1665 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1666 BOOL ret;
1667 HCRYPTKEY key;
1668 DWORD size;
1670 certInfo.SerialNumber.cbData = sizeof(serialNum);
1671 certInfo.SerialNumber.pbData = serialNum;
1672 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1673 certInfo.Issuer.pbData = encodedCommonName;
1674 signer.pCertInfo = &certInfo;
1675 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1676 signInfo.cSigners = 1;
1677 signInfo.rgSigners = &signer;
1679 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1680 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1681 if (!ret && GetLastError() == NTE_EXISTS) {
1682 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1683 PROV_RSA_FULL, 0);
1685 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1687 if (!ret) {
1688 skip("No context for tests\n");
1689 return;
1692 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1693 0, 0, &key);
1694 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1696 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1697 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1698 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1700 check_param("detached signed empty bare content", msg,
1701 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1702 sizeof(signedEmptyBareContent));
1703 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1704 signedEmptyContent, sizeof(signedEmptyContent));
1705 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1706 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1707 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1708 signedHash, sizeof(signedHash));
1709 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1710 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1711 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1712 detachedSignedContent, sizeof(detachedSignedContent));
1713 SetLastError(0xdeadbeef);
1714 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1715 ok(!ret && (GetLastError() == CRYPT_E_INVALID_INDEX ||
1716 broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */)),
1717 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1718 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1719 signedEncodedSigner, sizeof(signedEncodedSigner));
1721 CryptMsgClose(msg);
1723 certInfo.SerialNumber.cbData = 0;
1724 certInfo.Issuer.cbData = 0;
1725 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1726 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1727 U(signer.SignerId).KeyId.pbData = serialNum;
1728 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1729 NULL, NULL);
1730 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1731 check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM,
1732 signedKeyIdEmptyContent, sizeof(signedKeyIdEmptyContent));
1733 CryptMsgClose(msg);
1735 certInfo.SerialNumber.cbData = sizeof(serialNum);
1736 certInfo.SerialNumber.pbData = serialNum;
1737 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1738 certInfo.Issuer.pbData = encodedCommonName;
1739 signer.SignerId.dwIdChoice = 0;
1740 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1741 NULL, NULL);
1742 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1744 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1745 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1746 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1747 signedEmptyContent, sizeof(signedEmptyContent));
1748 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1749 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1750 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1751 signedBareContent, sizeof(signedBareContent));
1752 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1753 signedContent, sizeof(signedContent));
1755 CryptMsgClose(msg);
1757 signer.cAuthAttr = 1;
1758 signer.rgAuthAttr = &attr;
1759 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1760 NULL, NULL);
1761 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1763 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1764 check_param("signed with auth attrs bare content", msg,
1765 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1766 sizeof(signedWithAuthAttrsBareContent));
1768 CryptMsgClose(msg);
1770 signer.cAuthAttr = 0;
1771 signInfo.rgCertEncoded = &encodedCert;
1772 signInfo.cCertEncoded = 1;
1773 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1774 NULL, NULL);
1775 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1777 check_param("signed with cert empty bare content", msg,
1778 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1779 sizeof(signedWithCertEmptyBareContent));
1780 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1781 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1782 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1783 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1785 CryptMsgClose(msg);
1787 signInfo.cCertEncoded = 0;
1788 signInfo.rgCrlEncoded = &encodedCrl;
1789 signInfo.cCrlEncoded = 1;
1790 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1791 NULL, NULL);
1792 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1794 check_param("signed with crl empty bare content", msg,
1795 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1796 sizeof(signedWithCrlEmptyBareContent));
1797 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1798 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1799 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1800 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1802 CryptMsgClose(msg);
1804 signInfo.cCertEncoded = 1;
1805 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1806 NULL, NULL);
1807 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1809 check_param("signed with cert and crl empty bare content", msg,
1810 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1811 sizeof(signedWithCertAndCrlEmptyBareContent));
1812 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1813 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1814 check_param("signed with cert and crl bare content", msg,
1815 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1816 sizeof(signedWithCertAndCrlBareContent));
1818 CryptMsgClose(msg);
1820 /* Test with a cert with a (bogus) public key */
1821 signInfo.cCrlEncoded = 0;
1822 encodedCert.cbData = sizeof(v1CertWithPubKey);
1823 encodedCert.pbData = v1CertWithPubKey;
1824 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1825 NULL, NULL);
1826 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1827 check_param("signedWithCertWithPubKeyBareContent", msg,
1828 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1829 sizeof(signedWithCertWithPubKeyBareContent));
1830 CryptMsgClose(msg);
1832 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1833 encodedCert.pbData = v1CertWithValidPubKey;
1834 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1835 NULL, NULL);
1836 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1837 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1838 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1839 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1840 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1841 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1842 check_param("signedWithCertWithValidPubKeyContent", msg,
1843 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1844 sizeof(signedWithCertWithValidPubKeyContent));
1845 CryptMsgClose(msg);
1847 CryptDestroyKey(key);
1848 CryptReleaseContext(signer.hCryptProv, 0);
1849 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1850 CRYPT_DELETEKEYSET);
1853 static void test_signed_msg_get_param(void)
1855 BOOL ret;
1856 HCRYPTMSG msg;
1857 DWORD size, value = 0;
1858 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1859 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1860 CERT_INFO certInfo = { 0 };
1862 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1863 NULL, NULL);
1864 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1866 /* Content and bare content are always gettable */
1867 size = 0;
1868 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1869 ok(ret || broken(!ret /* Win9x */), "CryptMsgGetParam failed: %08x\n",
1870 GetLastError());
1871 if (!ret)
1873 skip("message parameters are broken, skipping tests\n");
1874 return;
1876 size = 0;
1877 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1878 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1879 /* For "signed" messages, so is the version. */
1880 size = 0;
1881 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1882 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1883 size = sizeof(value);
1884 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1885 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1886 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1887 /* But for this message, with no signers, the hash and signer aren't
1888 * available.
1890 size = 0;
1891 SetLastError(0xdeadbeef);
1892 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1893 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1894 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1895 SetLastError(0xdeadbeef);
1896 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1897 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1898 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1899 /* As usual, the type isn't available. */
1900 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1901 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1902 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1904 CryptMsgClose(msg);
1906 certInfo.SerialNumber.cbData = sizeof(serialNum);
1907 certInfo.SerialNumber.pbData = serialNum;
1908 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1909 certInfo.Issuer.pbData = encodedCommonName;
1910 signer.pCertInfo = &certInfo;
1911 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1912 signInfo.cSigners = 1;
1913 signInfo.rgSigners = &signer;
1915 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1916 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1917 if (!ret && GetLastError() == NTE_EXISTS) {
1918 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1919 PROV_RSA_FULL, 0);
1921 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1923 if (!ret) {
1924 skip("No context for tests\n");
1925 return;
1928 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1929 NULL, NULL);
1930 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1932 /* This message, with one signer, has the hash and signer for index 0
1933 * available, but not for other indexes.
1935 size = 0;
1936 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1937 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1938 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1939 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1940 size = 0;
1941 SetLastError(0xdeadbeef);
1942 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1943 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1944 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1945 SetLastError(0xdeadbeef);
1946 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1947 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1948 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1949 /* As usual, the type isn't available. */
1950 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1951 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1952 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1954 CryptMsgClose(msg);
1956 /* Opening the message using the CMS fields.. */
1957 certInfo.SerialNumber.cbData = 0;
1958 certInfo.Issuer.cbData = 0;
1959 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1960 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1961 sizeof(encodedCommonName);
1962 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1963 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1964 sizeof(serialNum);
1965 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1966 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1967 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1968 if (!ret && GetLastError() == NTE_EXISTS)
1969 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1970 PROV_RSA_FULL, 0);
1971 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1972 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1973 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1974 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1975 /* still results in the version being 1 when the issuer and serial number
1976 * are used and no additional CMS fields are used.
1978 size = sizeof(value);
1979 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1980 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE),
1981 "CryptMsgGetParam failed: %08x\n", GetLastError());
1982 if (ret)
1983 ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value);
1984 /* Apparently the encoded signer can be retrieved.. */
1985 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1986 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1987 /* but the signer info, CMS signer info, and cert ID can't be. */
1988 SetLastError(0xdeadbeef);
1989 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1990 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1991 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1992 SetLastError(0xdeadbeef);
1993 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1994 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1995 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1996 SetLastError(0xdeadbeef);
1997 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1998 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1999 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2000 CryptMsgClose(msg);
2002 /* Using the KeyId field of the SignerId results in the version becoming
2003 * the CMS version.
2005 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2006 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
2007 U(signer.SignerId).KeyId.pbData = serialNum;
2008 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
2009 PROV_RSA_FULL, CRYPT_NEWKEYSET);
2010 if (!ret && GetLastError() == NTE_EXISTS)
2011 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
2012 PROV_RSA_FULL, 0);
2013 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
2014 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
2015 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
2016 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
2017 size = sizeof(value);
2018 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
2019 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2020 if (ret)
2021 ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value);
2022 /* Even for a CMS message, the signer can be retrieved.. */
2023 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
2024 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2025 /* but the signer info, CMS signer info, and cert ID can't be. */
2026 SetLastError(0xdeadbeef);
2027 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2028 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2029 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2030 SetLastError(0xdeadbeef);
2031 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2032 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2033 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2034 SetLastError(0xdeadbeef);
2035 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
2036 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2037 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2038 CryptMsgClose(msg);
2040 CryptReleaseContext(signer.hCryptProv, 0);
2041 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
2042 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2045 static void test_signed_msg(void)
2047 test_signed_msg_open();
2048 test_signed_msg_update();
2049 test_signed_msg_encoding();
2050 test_signed_msg_get_param();
2053 static char oid_rsa_rc4[] = szOID_RSA_RC4;
2055 static void test_enveloped_msg_open(void)
2057 HCRYPTMSG msg;
2058 BOOL ret;
2059 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { 0 };
2060 PCCERT_CONTEXT context;
2062 SetLastError(0xdeadbeef);
2063 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2064 &envelopedInfo, NULL, NULL);
2065 ok(!msg && GetLastError() == E_INVALIDARG,
2066 "expected E_INVALIDARG, got %08x\n", GetLastError());
2068 envelopedInfo.cbSize = sizeof(envelopedInfo);
2069 SetLastError(0xdeadbeef);
2070 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2071 &envelopedInfo, NULL, NULL);
2072 ok(!msg &&
2073 (GetLastError() == CRYPT_E_UNKNOWN_ALGO ||
2074 GetLastError() == E_INVALIDARG), /* Win9x */
2075 "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", GetLastError());
2077 envelopedInfo.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4;
2078 SetLastError(0xdeadbeef);
2079 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2080 &envelopedInfo, NULL, NULL);
2081 ok(msg != NULL ||
2082 broken(!msg), /* Win9x */
2083 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2084 CryptMsgClose(msg);
2086 envelopedInfo.cRecipients = 1;
2087 if (!old_crypt32)
2089 SetLastError(0xdeadbeef);
2090 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2091 &envelopedInfo, NULL, NULL);
2092 ok(!msg && GetLastError() == E_INVALIDARG,
2093 "expected E_INVALIDARG, got %08x\n", GetLastError());
2096 context = CertCreateCertificateContext(X509_ASN_ENCODING,
2097 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
2098 if (context)
2100 envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo;
2101 SetLastError(0xdeadbeef);
2102 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2103 &envelopedInfo, NULL, NULL);
2104 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2105 CryptMsgClose(msg);
2106 SetLastError(0xdeadbeef);
2107 ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL,
2108 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
2109 ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
2110 SetLastError(0xdeadbeef);
2111 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2112 &envelopedInfo, NULL, NULL);
2113 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2114 CryptMsgClose(msg);
2115 CryptReleaseContext(envelopedInfo.hCryptProv, 0);
2116 CertFreeCertificateContext(context);
2118 else
2119 win_skip("failed to create certificate context, skipping tests\n");
2122 static void test_enveloped_msg_update(void)
2124 HCRYPTMSG msg;
2125 BOOL ret;
2126 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2127 { oid_rsa_rc4, { 0, NULL } }, NULL };
2128 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
2130 SetLastError(0xdeadbeef);
2131 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2132 &envelopedInfo, NULL, NULL);
2133 ok(msg != NULL ||
2134 broken(!msg), /* Win9x */
2135 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2136 if (msg)
2138 SetLastError(0xdeadbeef);
2139 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2140 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2141 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2142 SetLastError(0xdeadbeef);
2143 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2144 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2145 SetLastError(0xdeadbeef);
2146 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2147 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2148 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2149 CryptMsgClose(msg);
2151 SetLastError(0xdeadbeef);
2152 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2153 &envelopedInfo, NULL, NULL);
2154 ok(msg != NULL ||
2155 broken(!msg), /* Win9x */
2156 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2157 if (msg)
2159 SetLastError(0xdeadbeef);
2160 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2161 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2162 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2163 SetLastError(0xdeadbeef);
2164 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2165 ok(ret ||
2166 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2167 "CryptMsgUpdate failed: %08x\n", GetLastError());
2168 SetLastError(0xdeadbeef);
2169 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2170 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2171 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2172 CryptMsgClose(msg);
2174 SetLastError(0xdeadbeef);
2175 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2176 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2177 ok(msg != NULL ||
2178 broken(!msg), /* Win9x */
2179 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2180 if (msg)
2182 SetLastError(0xdeadbeef);
2183 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2184 ok(!ret && GetLastError() == E_INVALIDARG,
2185 "expected E_INVALIDARG, got %08x\n", GetLastError());
2186 SetLastError(0xdeadbeef);
2187 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2188 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2189 CryptMsgClose(msg);
2191 SetLastError(0xdeadbeef);
2192 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2193 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2194 ok(msg != NULL ||
2195 broken(!msg), /* Win9x */
2196 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2197 if (msg)
2199 SetLastError(0xdeadbeef);
2200 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2201 ok(!ret && GetLastError() == E_INVALIDARG,
2202 "expected E_INVALIDARG, got %08x\n", GetLastError());
2203 SetLastError(0xdeadbeef);
2204 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2205 ok(ret ||
2206 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2207 "CryptMsgUpdate failed: %08x\n", GetLastError());
2208 CryptMsgClose(msg);
2210 SetLastError(0xdeadbeef);
2211 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2212 &envelopedInfo, NULL, &streamInfo);
2213 ok(msg != NULL ||
2214 broken(!msg), /* Win9x */
2215 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2216 if (msg)
2218 SetLastError(0xdeadbeef);
2219 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2220 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2221 SetLastError(0xdeadbeef);
2222 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2223 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2224 CryptMsgClose(msg);
2226 SetLastError(0xdeadbeef);
2227 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2228 &envelopedInfo, NULL, &streamInfo);
2229 ok(msg != NULL ||
2230 broken(!msg), /* Win9x */
2231 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2232 if (msg)
2234 SetLastError(0xdeadbeef);
2235 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2236 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2237 SetLastError(0xdeadbeef);
2238 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2239 ok(ret ||
2240 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2241 "CryptMsgUpdate failed: %08x\n", GetLastError());
2242 CryptMsgClose(msg);
2246 static const BYTE envelopedEmptyBareContent[] = {
2247 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2248 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2249 0x03,0x04,0x05,0x00,0x80,0x00 };
2250 static const BYTE envelopedEmptyContent[] = {
2251 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24,
2252 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2253 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2254 0x03,0x04,0x05,0x00,0x80,0x00 };
2256 static void test_enveloped_msg_encoding(void)
2258 HCRYPTMSG msg;
2259 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2260 { oid_rsa_rc4, { 0, NULL } }, NULL };
2262 SetLastError(0xdeadbeef);
2263 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2264 &envelopedInfo, NULL, NULL);
2265 ok(msg != NULL ||
2266 broken(!msg), /* Win9x */
2267 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2268 if (msg)
2270 check_param("enveloped empty bare content", msg,
2271 CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent,
2272 sizeof(envelopedEmptyBareContent));
2273 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
2274 envelopedEmptyContent, sizeof(envelopedEmptyContent));
2275 CryptMsgClose(msg);
2279 static void test_enveloped_msg(void)
2281 test_enveloped_msg_open();
2282 test_enveloped_msg_update();
2283 test_enveloped_msg_encoding();
2286 static CRYPT_DATA_BLOB b4 = { 0, NULL };
2287 static const struct update_accum a4 = { 1, &b4 };
2289 static const BYTE bogusOIDContent[] = {
2290 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2291 0x04,0x00 };
2292 static const BYTE bogusHashContent[] = {
2293 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2294 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2295 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2296 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2297 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2298 static const BYTE envelopedBareContentWithoutData[] = {
2299 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2300 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2301 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2302 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2303 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b,
2304 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f,
2305 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94,
2306 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72,
2307 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18,
2308 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3,
2309 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6,
2310 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49,
2311 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e,
2312 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2313 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 };
2315 static void test_decode_msg_update(void)
2317 HCRYPTMSG msg;
2318 BOOL ret;
2319 CMSG_STREAM_INFO streamInfo = { 0 };
2320 DWORD i;
2321 struct update_accum accum = { 0, NULL };
2323 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2324 /* Update with a full message in a final update */
2325 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2326 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2327 /* Can't update after a final update */
2328 SetLastError(0xdeadbeef);
2329 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2330 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2331 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2332 CryptMsgClose(msg);
2334 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2335 /* Can't send a non-final update without streaming */
2336 SetLastError(0xdeadbeef);
2337 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2338 FALSE);
2339 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2340 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2341 /* A subsequent final update succeeds */
2342 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2343 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2344 CryptMsgClose(msg);
2346 if (!old_crypt32)
2348 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2349 /* Updating a message that has a NULL stream callback fails */
2350 SetLastError(0xdeadbeef);
2351 /* Crashes on some Win9x */
2352 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2353 FALSE);
2354 todo_wine
2355 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2356 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2357 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2358 GetLastError());
2359 /* Changing the callback pointer after the fact yields the same error (so
2360 * the message must copy the stream info, not just store a pointer to it)
2362 streamInfo.pfnStreamOutput = nop_stream_output;
2363 SetLastError(0xdeadbeef);
2364 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2365 FALSE);
2366 todo_wine
2367 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2368 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2369 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2370 GetLastError());
2371 CryptMsgClose(msg);
2374 /* Empty non-final updates are allowed when streaming.. */
2375 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2376 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2377 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2378 /* but final updates aren't when not enough data has been received. */
2379 SetLastError(0xdeadbeef);
2380 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2381 todo_wine
2382 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2383 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2384 CryptMsgClose(msg);
2386 /* Updating the message byte by byte is legal */
2387 streamInfo.pfnStreamOutput = accumulating_stream_output;
2388 streamInfo.pvArg = &accum;
2389 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2390 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2391 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2392 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2393 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2394 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2395 CryptMsgClose(msg);
2396 todo_wine
2397 check_updates("byte-by-byte empty content", &a4, &accum);
2398 free_updates(&accum);
2400 /* Decoding bogus content fails in non-streaming mode.. */
2401 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2402 SetLastError(0xdeadbeef);
2403 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2404 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2405 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2406 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2407 GetLastError());
2408 CryptMsgClose(msg);
2409 /* and as the final update in streaming mode.. */
2410 streamInfo.pfnStreamOutput = nop_stream_output;
2411 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2412 SetLastError(0xdeadbeef);
2413 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2414 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2415 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2416 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2417 GetLastError());
2418 CryptMsgClose(msg);
2419 /* and even as a non-final update in streaming mode. */
2420 streamInfo.pfnStreamOutput = nop_stream_output;
2421 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2422 SetLastError(0xdeadbeef);
2423 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2424 todo_wine
2425 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2426 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2427 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2428 GetLastError());
2429 CryptMsgClose(msg);
2431 /* An empty message can be opened with undetermined type.. */
2432 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2433 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2434 TRUE);
2435 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2436 CryptMsgClose(msg);
2437 /* but decoding it as an explicitly typed message fails. */
2438 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2439 NULL);
2440 SetLastError(0xdeadbeef);
2441 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2442 TRUE);
2443 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2444 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2445 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2446 GetLastError());
2447 CryptMsgClose(msg);
2448 /* On the other hand, decoding the bare content of an empty message fails
2449 * with unspecified type..
2451 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2452 SetLastError(0xdeadbeef);
2453 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2454 sizeof(dataEmptyBareContent), TRUE);
2455 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2456 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2457 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2458 GetLastError());
2459 CryptMsgClose(msg);
2460 /* but succeeds with explicit type. */
2461 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2462 NULL);
2463 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2464 sizeof(dataEmptyBareContent), TRUE);
2465 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2466 CryptMsgClose(msg);
2468 /* Decoding valid content with an unsupported OID fails */
2469 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2470 SetLastError(0xdeadbeef);
2471 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2472 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2473 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2474 CryptMsgClose(msg);
2476 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2477 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2478 SetLastError(0xdeadbeef);
2479 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2480 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2481 "CryptMsgUpdate failed: %08x\n", GetLastError());
2482 CryptMsgClose(msg);
2483 /* while with specified type it fails. */
2484 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2485 NULL);
2486 SetLastError(0xdeadbeef);
2487 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2488 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2489 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2490 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2491 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2492 GetLastError());
2493 CryptMsgClose(msg);
2494 /* On the other hand, decoding the bare content of an empty hash message
2495 * fails with unspecified type..
2497 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2498 SetLastError(0xdeadbeef);
2499 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2500 sizeof(hashEmptyBareContent), TRUE);
2501 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2502 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2503 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2504 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2505 GetLastError());
2506 CryptMsgClose(msg);
2507 /* but succeeds with explicit type. */
2508 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2509 NULL);
2510 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2511 sizeof(hashEmptyBareContent), TRUE);
2512 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2513 "CryptMsgUpdate failed: %x\n", GetLastError());
2514 CryptMsgClose(msg);
2516 /* And again, opening a (non-empty) hash message with unspecified type
2517 * succeeds..
2519 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2520 SetLastError(0xdeadbeef);
2521 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2522 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2523 CryptMsgClose(msg);
2524 /* while with specified type it fails.. */
2525 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2526 NULL);
2527 SetLastError(0xdeadbeef);
2528 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2529 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2530 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2531 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2532 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2533 GetLastError());
2534 CryptMsgClose(msg);
2535 /* and decoding the bare content of a non-empty hash message fails with
2536 * unspecified type..
2538 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2539 SetLastError(0xdeadbeef);
2540 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2541 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2542 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2543 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2544 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2545 GetLastError());
2546 CryptMsgClose(msg);
2547 /* but succeeds with explicit type. */
2548 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2549 NULL);
2550 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2551 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2552 CryptMsgClose(msg);
2554 /* Opening a (non-empty) hash message with unspecified type and a bogus
2555 * hash value succeeds..
2557 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2558 SetLastError(0xdeadbeef);
2559 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2560 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2561 CryptMsgClose(msg);
2563 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2564 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2565 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2566 CryptMsgClose(msg);
2567 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2568 SetLastError(0xdeadbeef);
2569 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2570 sizeof(signedWithCertAndCrlBareContent), TRUE);
2571 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2572 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2573 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2574 GetLastError());
2575 CryptMsgClose(msg);
2576 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2577 NULL);
2578 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2579 sizeof(signedWithCertAndCrlBareContent), TRUE);
2580 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2581 CryptMsgClose(msg);
2583 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2584 NULL, NULL);
2585 /* The first update succeeds.. */
2586 ret = CryptMsgUpdate(msg, detachedSignedContent,
2587 sizeof(detachedSignedContent), TRUE);
2588 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2589 /* as does a second (probably to update the detached portion).. */
2590 ret = CryptMsgUpdate(msg, detachedSignedContent,
2591 sizeof(detachedSignedContent), TRUE);
2592 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2593 /* while a third fails. */
2594 ret = CryptMsgUpdate(msg, detachedSignedContent,
2595 sizeof(detachedSignedContent), TRUE);
2596 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2597 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2598 CryptMsgClose(msg);
2600 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2601 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2602 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2603 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2604 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2605 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2606 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2607 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2608 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2610 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2611 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2612 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2613 CryptMsgClose(msg);
2615 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2616 NULL);
2617 SetLastError(0xdeadbeef);
2618 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2619 sizeof(envelopedEmptyBareContent), TRUE);
2620 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2621 CryptMsgClose(msg);
2623 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2624 NULL);
2625 SetLastError(0xdeadbeef);
2626 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2627 sizeof(envelopedEmptyContent), TRUE);
2628 ok(!ret &&
2629 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2630 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2631 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2632 CryptMsgClose(msg);
2634 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2635 SetLastError(0xdeadbeef);
2636 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2637 sizeof(envelopedEmptyBareContent), TRUE);
2638 ok(!ret &&
2639 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2640 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2641 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2642 CryptMsgClose(msg);
2644 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2645 SetLastError(0xdeadbeef);
2646 ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2647 sizeof(envelopedEmptyContent), TRUE);
2648 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2649 CryptMsgClose(msg);
2651 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2652 NULL);
2653 SetLastError(0xdeadbeef);
2654 ret = CryptMsgUpdate(msg, envelopedBareContentWithoutData,
2655 sizeof(envelopedBareContentWithoutData), TRUE);
2656 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2657 CryptMsgClose(msg);
2660 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2661 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2663 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2664 const CMSG_SIGNER_INFO *expected)
2666 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2667 expected->dwVersion, got->dwVersion);
2668 ok(got->Issuer.cbData == expected->Issuer.cbData,
2669 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2670 got->Issuer.cbData);
2671 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2672 "Unexpected issuer\n");
2673 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2674 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2675 got->SerialNumber.cbData);
2676 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2677 got->SerialNumber.cbData), "Unexpected serial number\n");
2678 /* FIXME: check more things */
2681 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2682 const CMSG_CMS_SIGNER_INFO *expected)
2684 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2685 expected->dwVersion, got->dwVersion);
2686 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2687 "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2688 got->SignerId.dwIdChoice);
2689 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2691 if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2693 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2694 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2695 "Expected issuer size %d, got %d\n",
2696 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2697 U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2698 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2699 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2700 U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2701 "Unexpected issuer\n");
2702 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2703 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2704 "Expected serial number size %d, got %d\n",
2705 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2706 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2707 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2708 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2709 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2710 "Unexpected serial number\n");
2712 else
2714 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2715 "expected key id size %d, got %d\n",
2716 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2717 ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2718 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2719 "unexpected key id\n");
2722 /* FIXME: check more things */
2725 static const BYTE signedWithCertAndCrlComputedHash[] = {
2726 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2727 0x2f };
2728 static BYTE keyIdIssuer[] = {
2729 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2730 0x0a,0x07,0x01,0x04,0x01,0x01 };
2731 static const BYTE publicPrivateKeyPair[] = {
2732 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00,
2733 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b,
2734 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50,
2735 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54,
2736 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39,
2737 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7,
2738 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48,
2739 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17,
2740 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54,
2741 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33,
2742 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52,
2743 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e,
2744 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61,
2745 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb,
2746 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02,
2747 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90,
2748 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e,
2749 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce,
2750 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14,
2751 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5,
2752 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5,
2753 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94,
2754 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68,
2755 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71,
2756 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25,
2757 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc,
2758 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a,
2759 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64,
2760 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77,
2761 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68,
2762 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab,
2763 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9,
2764 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed,
2765 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01,
2766 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e,
2767 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71,
2768 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0,
2769 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87,
2770 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b,
2771 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e };
2772 static const BYTE envelopedMessage[] = {
2773 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,
2774 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,
2775 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,
2776 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,
2777 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
2778 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65,
2779 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae,
2780 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1,
2781 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51,
2782 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf,
2783 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b,
2784 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e,
2785 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e,
2786 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70,
2787 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,
2788 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,
2789 0x04,0x5f,0x80,0xf2,0x17 };
2790 static const BYTE envelopedBareMessage[] = {
2791 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2792 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2793 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2794 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2795 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d,
2796 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d,
2797 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5,
2798 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e,
2799 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2,
2800 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4,
2801 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70,
2802 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c,
2803 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55,
2804 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2805 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c,
2806 0x2d,0xa3,0x6e };
2807 static const BYTE envelopedMessageWith3Recps[] = {
2808 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,
2809 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e,
2810 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,
2811 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,
2812 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,
2813 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e,
2814 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba,
2815 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f,
2816 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5,
2817 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21,
2818 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae,
2819 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0,
2820 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96,
2821 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae,
2822 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,
2823 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,
2824 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6,
2825 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
2826 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf,
2827 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9,
2828 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3,
2829 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02,
2830 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70,
2831 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3,
2832 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74,
2833 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94,
2834 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7,
2835 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,
2836 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,
2837 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
2838 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98,
2839 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5,
2840 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9,
2841 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3,
2842 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8,
2843 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac,
2844 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc,
2845 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5,
2846 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1,
2847 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
2848 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,
2849 0x80,0x04,0x4e,0x99,0x9d,0x4c };
2850 static const BYTE serialNumber[] = {
2851 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2,
2852 0x1c };
2853 static const BYTE issuer[] = {
2854 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 };
2856 static void test_decode_msg_get_param(void)
2858 HCRYPTMSG msg;
2859 HCRYPTPROV hCryptProv;
2860 HCRYPTKEY key = 0;
2861 BOOL ret;
2862 DWORD size = 0, value;
2863 LPBYTE buf;
2864 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2866 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2867 SetLastError(0xdeadbeef);
2868 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2869 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2870 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2871 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2872 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2873 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2874 sizeof(msgData));
2875 CryptMsgClose(msg);
2877 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2878 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2879 if (ret)
2881 /* Crashes on some Win9x */
2882 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2883 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2884 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2885 emptyHashParam, sizeof(emptyHashParam));
2887 CryptMsgClose(msg);
2888 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2889 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2890 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2891 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2892 sizeof(msgData));
2893 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2894 sizeof(hashParam));
2895 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2896 hashParam, sizeof(hashParam));
2897 /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2898 * even though there's only one hash.
2900 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2901 ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2902 "CryptMsgGetParam failed: %08x\n", GetLastError());
2903 if (ret)
2904 buf = CryptMemAlloc(size);
2905 else
2906 buf = NULL;
2907 if (buf)
2909 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2910 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2911 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2912 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2913 CryptMemFree(buf);
2915 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2916 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2917 value = CMSG_HASHED_DATA_V0;
2918 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2919 sizeof(value));
2920 CryptMsgClose(msg);
2922 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2923 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2924 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2925 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2926 sizeof(msgData));
2927 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2928 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2929 size = sizeof(value);
2930 value = 2112;
2931 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2932 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2933 ok(value == 1, "Expected 1 signer, got %d\n", value);
2934 size = 0;
2935 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2936 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2937 "CryptMsgGetParam failed: %08x\n", GetLastError());
2938 if (ret)
2939 buf = CryptMemAlloc(size);
2940 else
2941 buf = NULL;
2942 if (buf)
2944 CMSG_SIGNER_INFO signer = { 0 };
2946 signer.dwVersion = 1;
2947 signer.Issuer.cbData = sizeof(encodedCommonName);
2948 signer.Issuer.pbData = encodedCommonName;
2949 signer.SerialNumber.cbData = sizeof(serialNum);
2950 signer.SerialNumber.pbData = serialNum;
2951 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2952 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2953 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2954 CryptMemFree(buf);
2956 /* Getting the CMS signer info of a PKCS7 message is possible. */
2957 size = 0;
2958 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2959 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2960 "CryptMsgGetParam failed: %08x\n", GetLastError());
2961 if (ret)
2962 buf = CryptMemAlloc(size);
2963 else
2964 buf = NULL;
2965 if (buf)
2967 CMSG_CMS_SIGNER_INFO signer = { 0 };
2969 signer.dwVersion = 1;
2970 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2971 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2972 sizeof(encodedCommonName);
2973 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2974 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2975 sizeof(serialNum);
2976 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2977 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2978 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2979 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2980 CryptMemFree(buf);
2982 /* index is ignored when getting signer count */
2983 size = sizeof(value);
2984 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2985 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2986 ok(value == 1, "Expected 1 signer, got %d\n", value);
2987 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2988 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2989 ok(value == 0, "Expected 0 certs, got %d\n", value);
2990 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2991 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2992 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2993 CryptMsgClose(msg);
2994 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2995 NULL);
2996 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2997 sizeof(signedWithCertAndCrlBareContent), TRUE);
2998 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2999 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
3000 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3001 ok(value == 1, "Expected 1 cert, got %d\n", value);
3002 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
3003 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
3004 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3005 ok(value == 1, "Expected 1 CRL, got %d\n", value);
3006 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
3007 check_param("signed with cert and CRL computed hash", msg,
3008 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
3009 sizeof(signedWithCertAndCrlComputedHash));
3010 CryptMsgClose(msg);
3012 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3013 ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
3014 sizeof(signedKeyIdEmptyContent), TRUE);
3015 if (!ret && GetLastError() == OSS_DATA_ERROR)
3017 CryptMsgClose(msg);
3018 win_skip("Subsequent tests crash on some Win9x\n");
3019 return;
3021 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3022 size = sizeof(value);
3023 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
3024 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3025 ok(value == 1, "Expected 1 signer, got %d\n", value);
3026 /* Getting the regular (non-CMS) signer info from a CMS message is also
3027 * possible..
3029 size = 0;
3030 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
3031 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3032 if (ret)
3033 buf = CryptMemAlloc(size);
3034 else
3035 buf = NULL;
3036 if (buf)
3038 CMSG_SIGNER_INFO signer;
3039 BYTE zero = 0;
3041 /* and here's the little oddity: for a CMS message using the key id
3042 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
3043 * a signer with a zero (not empty) serial number, and whose issuer is
3044 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
3045 * and value of the key id.
3047 signer.dwVersion = CMSG_SIGNED_DATA_V3;
3048 signer.Issuer.cbData = sizeof(keyIdIssuer);
3049 signer.Issuer.pbData = keyIdIssuer;
3050 signer.SerialNumber.cbData = 1;
3051 signer.SerialNumber.pbData = &zero;
3052 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
3053 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
3054 CryptMemFree(buf);
3056 size = 0;
3057 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
3058 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3059 if (ret)
3060 buf = CryptMemAlloc(size);
3061 else
3062 buf = NULL;
3063 if (buf)
3065 CMSG_CMS_SIGNER_INFO signer = { 0 };
3067 signer.dwVersion = CMSG_SIGNED_DATA_V3;
3068 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
3069 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
3070 U(signer.SignerId).KeyId.pbData = serialNum;
3071 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3072 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
3073 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
3074 CryptMemFree(buf);
3076 CryptMsgClose(msg);
3078 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3079 NULL);
3080 CryptMsgUpdate(msg, envelopedEmptyBareContent,
3081 sizeof(envelopedEmptyBareContent), TRUE);
3082 check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL,
3084 CryptMsgClose(msg);
3086 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3087 CryptMsgUpdate(msg, envelopedEmptyContent, sizeof(envelopedEmptyContent),
3088 TRUE);
3089 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0);
3090 CryptMsgClose(msg);
3092 pCryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL,
3093 CRYPT_VERIFYCONTEXT);
3094 SetLastError(0xdeadbeef);
3095 ret = CryptImportKey(hCryptProv, publicPrivateKeyPair,
3096 sizeof(publicPrivateKeyPair), 0, 0, &key);
3097 ok(ret ||
3098 broken(!ret && GetLastError() == NTE_PERM), /* WinME and some NT4 */
3099 "CryptImportKey failed: %08x\n", GetLastError());
3101 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3102 CryptMsgUpdate(msg, envelopedMessage, sizeof(envelopedMessage), TRUE);
3103 check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM,
3104 envelopedMessage + sizeof(envelopedMessage) - 4, 4);
3105 if (key)
3107 decryptPara.hCryptProv = hCryptProv;
3108 SetLastError(0xdeadbeef);
3109 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3110 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3111 decryptPara.hCryptProv = 0;
3112 SetLastError(0xdeadbeef);
3113 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3114 ok(!ret && GetLastError() == CRYPT_E_ALREADY_DECRYPTED,
3115 "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError());
3116 check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData,
3117 sizeof(msgData));
3119 else
3120 win_skip("failed to import a key, skipping tests\n");
3121 CryptMsgClose(msg);
3123 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3124 NULL);
3125 CryptMsgUpdate(msg, envelopedBareMessage, sizeof(envelopedBareMessage),
3126 TRUE);
3127 check_param("enveloped bare message before decrypting", msg,
3128 CMSG_CONTENT_PARAM, envelopedBareMessage +
3129 sizeof(envelopedBareMessage) - 4, 4);
3130 if (key)
3132 decryptPara.hCryptProv = hCryptProv;
3133 SetLastError(0xdeadbeef);
3134 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3135 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3136 check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData,
3137 sizeof(msgData));
3139 else
3140 win_skip("failed to import a key, skipping tests\n");
3141 CryptMsgClose(msg);
3143 if (key)
3144 CryptDestroyKey(key);
3145 CryptReleaseContext(hCryptProv, 0);
3147 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3148 CryptMsgUpdate(msg, envelopedMessageWith3Recps,
3149 sizeof(envelopedMessageWith3Recps), TRUE);
3150 value = 3;
3151 check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM,
3152 (const BYTE *)&value, sizeof(value));
3153 size = 0;
3154 SetLastError(0xdeadbeef);
3155 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 3, NULL, &size);
3156 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3157 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3158 size = 0;
3159 SetLastError(0xdeadbeef);
3160 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, NULL, &size);
3161 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3162 ok(size >= 142, "unexpected size: %u\n", size);
3163 if (ret)
3164 buf = CryptMemAlloc(size);
3165 else
3166 buf = NULL;
3167 if (buf)
3169 CERT_INFO *certInfo = (CERT_INFO *)buf;
3171 SetLastError(0xdeadbeef);
3172 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, buf, &size);
3173 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3174 ok(certInfo->SerialNumber.cbData == sizeof(serialNumber),
3175 "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData);
3176 ok(!memcmp(certInfo->SerialNumber.pbData, serialNumber,
3177 sizeof(serialNumber)), "unexpected serial number\n");
3178 ok(certInfo->Issuer.cbData == sizeof(issuer),
3179 "unexpected issuer size: %u\n", certInfo->Issuer.cbData);
3180 ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)),
3181 "unexpected issuer\n");
3182 CryptMemFree(buf);
3184 CryptMsgClose(msg);
3187 static void test_decode_msg(void)
3189 test_decode_msg_update();
3190 test_decode_msg_get_param();
3193 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
3194 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
3195 static BYTE encodedPubKey[] = {
3196 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
3197 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
3198 0x0d,0x0e,0x0f };
3199 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
3200 static BYTE mod_encoded[] = {
3201 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
3202 0x01,0x00,0x01 };
3204 static void test_msg_control(void)
3206 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3207 BOOL ret;
3208 HCRYPTMSG msg;
3209 DWORD i;
3210 CERT_INFO certInfo = { 0 };
3211 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
3212 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
3213 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
3215 /* Crashes
3216 ret = CryptMsgControl(NULL, 0, 0, NULL);
3219 /* Data encode messages don't allow any sort of control.. */
3220 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
3221 NULL);
3222 /* either with no prior update.. */
3223 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3225 SetLastError(0xdeadbeef);
3226 ret = CryptMsgControl(msg, 0, i, NULL);
3227 ok(!ret && GetLastError() == E_INVALIDARG,
3228 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3230 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3231 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3232 /* or after an update. */
3233 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3235 SetLastError(0xdeadbeef);
3236 ret = CryptMsgControl(msg, 0, i, NULL);
3237 ok(!ret && GetLastError() == E_INVALIDARG,
3238 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3240 CryptMsgClose(msg);
3242 /* Hash encode messages don't allow any sort of control.. */
3243 hashInfo.cbSize = sizeof(hashInfo);
3244 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
3245 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
3246 NULL, NULL);
3247 /* either with no prior update.. */
3248 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3250 SetLastError(0xdeadbeef);
3251 ret = CryptMsgControl(msg, 0, i, NULL);
3252 ok(!ret && GetLastError() == E_INVALIDARG,
3253 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3255 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3256 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3257 /* or after an update. */
3258 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3260 SetLastError(0xdeadbeef);
3261 ret = CryptMsgControl(msg, 0, i, NULL);
3262 ok(!ret && GetLastError() == E_INVALIDARG,
3263 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3265 CryptMsgClose(msg);
3267 /* Signed encode messages likewise don't allow any sort of control.. */
3268 signInfo.cbSize = sizeof(signInfo);
3269 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
3270 NULL, NULL);
3271 /* either before an update.. */
3272 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3274 SetLastError(0xdeadbeef);
3275 ret = CryptMsgControl(msg, 0, i, NULL);
3276 ok(!ret && GetLastError() == E_INVALIDARG,
3277 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3279 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3280 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3281 /* or after an update. */
3282 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3284 SetLastError(0xdeadbeef);
3285 ret = CryptMsgControl(msg, 0, i, NULL);
3286 ok(!ret && GetLastError() == E_INVALIDARG,
3287 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3289 CryptMsgClose(msg);
3291 /* Decode messages behave a bit differently. */
3292 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3293 /* Bad control type */
3294 SetLastError(0xdeadbeef);
3295 ret = CryptMsgControl(msg, 0, 0, NULL);
3296 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3297 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3298 SetLastError(0xdeadbeef);
3299 ret = CryptMsgControl(msg, 1, 0, NULL);
3300 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3301 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3302 /* Can't verify the hash of an indeterminate-type message */
3303 SetLastError(0xdeadbeef);
3304 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3305 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3306 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3307 /* Crashes
3308 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
3310 /* Can't decrypt an indeterminate-type message */
3311 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3312 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3313 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3314 CryptMsgClose(msg);
3316 if (!old_crypt32)
3318 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3319 NULL);
3320 /* Can't verify the hash of an empty message */
3321 SetLastError(0xdeadbeef);
3322 /* Crashes on some Win9x */
3323 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3324 todo_wine
3325 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3326 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3327 /* Crashes
3328 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3330 /* Can't verify the signature of a hash message */
3331 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3332 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3333 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3334 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
3335 TRUE);
3336 /* Oddly enough, this fails, crashes on some Win9x */
3337 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3338 ok(!ret, "Expected failure\n");
3339 CryptMsgClose(msg);
3341 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3342 NULL);
3343 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
3344 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3345 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3346 /* Can't decrypt an indeterminate-type message */
3347 SetLastError(0xdeadbeef);
3348 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3349 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3350 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3351 CryptMsgClose(msg);
3353 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3354 NULL, NULL);
3355 /* Can't verify the hash of a detached message before it's been updated. */
3356 SetLastError(0xdeadbeef);
3357 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3358 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3359 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3360 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3361 TRUE);
3362 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3363 /* Still can't verify the hash of a detached message with the content
3364 * of the detached hash given..
3366 SetLastError(0xdeadbeef);
3367 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3368 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
3369 "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
3370 /* and giving the content of the message after attempting to verify the
3371 * hash fails.
3373 SetLastError(0xdeadbeef);
3374 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3375 todo_wine
3376 ok(!ret &&
3377 (GetLastError() == NTE_BAD_HASH_STATE ||
3378 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3379 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
3380 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3381 "got %08x\n", GetLastError());
3382 CryptMsgClose(msg);
3384 /* Finally, verifying the hash of a detached message in the correct order:
3385 * 1. Update with the detached hash message
3386 * 2. Update with the content of the message
3387 * 3. Verifying the hash of the message
3388 * succeeds.
3390 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3391 NULL, NULL);
3392 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3393 TRUE);
3394 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3395 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3396 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3397 SetLastError(0xdeadbeef);
3398 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3399 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3400 CryptMsgClose(msg);
3402 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3403 NULL);
3404 /* Can't verify the hash of a signed message */
3405 SetLastError(0xdeadbeef);
3406 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3407 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3408 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3409 /* Can't decrypt a signed message */
3410 SetLastError(0xdeadbeef);
3411 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3412 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3413 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3414 /* Crash
3415 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3416 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3418 CryptMsgUpdate(msg, signedWithCertBareContent,
3419 sizeof(signedWithCertBareContent), TRUE);
3420 /* With an empty cert info, the signer can't be found in the message (and
3421 * the signature can't be verified.
3423 SetLastError(0xdeadbeef);
3424 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3425 ok(!ret && (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND ||
3426 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3427 "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n",
3428 GetLastError());
3429 /* The cert info is expected to have an issuer, serial number, and public
3430 * key info set.
3432 certInfo.SerialNumber.cbData = sizeof(serialNum);
3433 certInfo.SerialNumber.pbData = serialNum;
3434 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3435 certInfo.Issuer.pbData = encodedCommonName;
3436 SetLastError(0xdeadbeef);
3437 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3438 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3439 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3440 "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError());
3441 CryptMsgClose(msg);
3442 /* This cert has a public key, but it's not in a usable form */
3443 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3444 NULL);
3445 ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
3446 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
3447 if (ret)
3449 /* Crashes on some Win9x */
3450 /* Again, cert info needs to have a public key set */
3451 SetLastError(0xdeadbeef);
3452 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3453 ok(!ret &&
3454 (GetLastError() == CRYPT_E_ASN1_EOD ||
3455 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3456 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3457 /* The public key is supposed to be in encoded form.. */
3458 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3459 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3460 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
3461 SetLastError(0xdeadbeef);
3462 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3463 ok(!ret &&
3464 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3465 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3466 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3467 /* but not as a X509_PUBLIC_KEY_INFO.. */
3468 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3469 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
3470 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
3471 SetLastError(0xdeadbeef);
3472 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3473 ok(!ret &&
3474 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3475 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3476 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3477 /* This decodes successfully, but it doesn't match any key in the message */
3478 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
3479 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
3480 SetLastError(0xdeadbeef);
3481 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3482 /* In Wine's rsaenh, this fails to decode because the key length is too
3483 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
3484 * now.
3486 todo_wine
3487 ok(!ret &&
3488 (GetLastError() == NTE_BAD_SIGNATURE ||
3489 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3490 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3492 CryptMsgClose(msg);
3493 /* A message with no data doesn't have a valid signature */
3494 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3495 ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
3496 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
3497 if (ret)
3499 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3500 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
3501 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
3502 SetLastError(0xdeadbeef);
3503 /* Crashes on some Win9x */
3504 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3505 ok(!ret &&
3506 (GetLastError() == NTE_BAD_SIGNATURE ||
3507 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3508 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3510 CryptMsgClose(msg);
3511 /* Finally, this succeeds */
3512 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3513 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3514 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3515 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3516 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3517 "CryptMsgControl failed: %08x\n", GetLastError());
3518 CryptMsgClose(msg);
3520 /* Test verifying signature of a detached signed message */
3521 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3522 NULL, NULL);
3523 ret = CryptMsgUpdate(msg, detachedSignedContent,
3524 sizeof(detachedSignedContent), TRUE);
3525 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3526 /* Can't verify the sig without having updated the data */
3527 SetLastError(0xdeadbeef);
3528 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3529 ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
3530 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3531 "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n",
3532 GetLastError());
3533 /* Now that the signature's been checked, can't do the final update */
3534 SetLastError(0xdeadbeef);
3535 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3536 todo_wine
3537 ok((!ret &&
3538 (GetLastError() == NTE_BAD_HASH_STATE ||
3539 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3540 GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */
3541 broken(ret), /* Win9x */
3542 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3543 "got %08x\n", GetLastError());
3544 CryptMsgClose(msg);
3545 /* Updating with the detached portion of the message and the data of the
3546 * the message allows the sig to be verified.
3548 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3549 NULL, NULL);
3550 ret = CryptMsgUpdate(msg, detachedSignedContent,
3551 sizeof(detachedSignedContent), TRUE);
3552 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3553 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3554 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3555 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3556 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3557 "CryptMsgControl failed: %08x\n", GetLastError());
3558 CryptMsgClose(msg);
3560 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3561 NULL);
3562 decryptPara.cbSize = 0;
3563 SetLastError(0xdeadbeef);
3564 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3565 ok(!ret && GetLastError() == E_INVALIDARG,
3566 "expected E_INVALIDARG, got %08x\n", GetLastError());
3567 decryptPara.cbSize = sizeof(decryptPara);
3568 if (!old_crypt32)
3570 SetLastError(0xdeadbeef);
3571 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3572 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3573 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3575 SetLastError(0xdeadbeef);
3576 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
3577 sizeof(envelopedEmptyBareContent), TRUE);
3578 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3579 SetLastError(0xdeadbeef);
3580 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3581 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3582 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3583 CryptMsgClose(msg);
3585 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3586 NULL);
3587 SetLastError(0xdeadbeef);
3588 ret = CryptMsgUpdate(msg, envelopedBareMessage,
3589 sizeof(envelopedBareMessage), TRUE);
3590 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3591 SetLastError(0xdeadbeef);
3592 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3593 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
3594 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
3595 CryptMsgClose(msg);
3598 /* win9x has much less parameter checks and will crash on many tests
3599 * this code is from test_signed_msg_update()
3601 static BOOL detect_nt(void)
3603 BOOL ret;
3604 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
3605 CERT_INFO certInfo = { 0 };
3607 if (!pCryptAcquireContextW)
3608 return FALSE;
3610 certInfo.SerialNumber.cbData = sizeof(serialNum);
3611 certInfo.SerialNumber.pbData = serialNum;
3612 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3613 certInfo.Issuer.pbData = encodedCommonName;
3614 signer.pCertInfo = &certInfo;
3615 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3617 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3618 PROV_RSA_FULL, CRYPT_NEWKEYSET);
3619 if (!ret && GetLastError() == NTE_EXISTS) {
3620 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3621 PROV_RSA_FULL, 0);
3624 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
3626 /* cleanup */
3627 CryptReleaseContext(signer.hCryptProv, 0);
3628 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
3629 CRYPT_DELETEKEYSET);
3631 return TRUE;
3634 static void test_msg_get_and_verify_signer(void)
3636 BOOL ret;
3637 HCRYPTMSG msg;
3638 PCCERT_CONTEXT signer;
3639 DWORD signerIndex;
3640 HCERTSTORE store;
3642 /* Crash */
3643 if (0)
3645 CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
3646 CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3649 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3650 /* An empty message has no signer */
3651 SetLastError(0xdeadbeef);
3652 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3653 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3654 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3655 /* The signer is cleared on error */
3656 signer = (PCCERT_CONTEXT)0xdeadbeef;
3657 SetLastError(0xdeadbeef);
3658 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3659 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3660 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3661 ok(!signer, "expected signer to be NULL\n");
3662 /* The signer index is also cleared on error */
3663 signerIndex = 0xdeadbeef;
3664 SetLastError(0xdeadbeef);
3665 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3666 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3667 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3668 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
3669 /* An unsigned message (msgData isn't a signed message at all)
3670 * likewise has no signer.
3672 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3673 SetLastError(0xdeadbeef);
3674 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3675 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3676 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3677 CryptMsgClose(msg);
3679 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3680 /* A "signed" message created with no signer cert likewise has no signer */
3681 ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
3682 if (ret)
3684 /* Crashes on most Win9x */
3685 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3686 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3687 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3689 CryptMsgClose(msg);
3691 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3692 /* A signed message succeeds, .. */
3693 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3694 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3695 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3696 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3697 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3698 /* the signer index can be retrieved, .. */
3699 signerIndex = 0xdeadbeef;
3700 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3701 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3702 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3703 if (ret)
3704 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
3705 /* as can the signer cert. */
3706 signer = (PCCERT_CONTEXT)0xdeadbeef;
3707 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3708 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3709 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3710 if (ret)
3711 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3712 "expected a valid signer\n");
3713 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3714 CertFreeCertificateContext(signer);
3715 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3717 signerIndex = 0xdeadbeef;
3718 SetLastError(0xdeadbeef);
3719 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3720 NULL, &signerIndex);
3721 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3722 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3723 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3724 * message signer not to be found.
3726 SetLastError(0xdeadbeef);
3727 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3728 NULL, NULL);
3729 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3730 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3731 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3732 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3733 * the message signer not to be found.
3735 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3736 CERT_STORE_CREATE_NEW_FLAG, NULL);
3737 SetLastError(0xdeadbeef);
3738 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3739 NULL, NULL);
3740 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3741 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3742 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3743 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3744 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3745 CERT_STORE_ADD_ALWAYS, NULL);
3746 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win98 */),
3747 "CertAddEncodedCertificateToStore failed: 0x%08x\n", GetLastError());
3748 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3749 * the signer succeeds.
3751 SetLastError(0xdeadbeef);
3752 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3753 NULL, NULL);
3754 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3755 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3756 CertCloseStore(store, 0);
3757 CryptMsgClose(msg);
3760 START_TEST(msg)
3762 init_function_pointers();
3763 have_nt = detect_nt();
3764 if (!have_nt)
3765 win_skip("Win9x crashes on some parameter checks\n");
3767 /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
3768 if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
3770 win_skip("Some tests will crash on older crypt32 implementations\n");
3771 old_crypt32 = TRUE;
3774 /* Basic parameter checking tests */
3775 test_msg_open_to_encode();
3776 test_msg_open_to_decode();
3777 test_msg_get_param();
3778 test_msg_close();
3779 test_msg_control();
3781 /* Message-type specific tests */
3782 test_data_msg();
3783 test_hash_msg();
3784 test_signed_msg();
3785 test_enveloped_msg();
3786 test_decode_msg();
3788 test_msg_get_and_verify_signer();