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