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