push 421a6d0d1068c98851feb4eb01bb0e754f615ce9
[wine/hacks.git] / dlls / crypt32 / tests / msg.c
blob33b29c31a3a629bf473d475944c7c071017437b4
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 char oid_rsa_md5[] = szOID_RSA_MD5;
32 static BOOL (WINAPI * pCryptAcquireContextW)
33 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
35 static void init_function_pointers(void)
37 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
39 #define GET_PROC(dll, func) \
40 p ## func = (void *)GetProcAddress(dll, #func); \
41 if(!p ## func) \
42 trace("GetProcAddress(%s) failed\n", #func);
44 GET_PROC(hAdvapi32, CryptAcquireContextW)
46 #undef GET_PROC
49 static void test_msg_open_to_encode(void)
51 HCRYPTMSG msg;
53 /* Crash
54 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
55 NULL, NULL);
56 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
57 NULL);
58 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
59 NULL);
62 /* Bad encodings */
63 SetLastError(0xdeadbeef);
64 msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
65 ok(!msg && GetLastError() == E_INVALIDARG,
66 "Expected E_INVALIDARG, got %x\n", GetLastError());
67 SetLastError(0xdeadbeef);
68 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
69 ok(!msg && GetLastError() == E_INVALIDARG,
70 "Expected E_INVALIDARG, got %x\n", GetLastError());
72 /* Bad message types */
73 SetLastError(0xdeadbeef);
74 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
75 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
76 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
77 SetLastError(0xdeadbeef);
78 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
79 NULL, NULL, NULL);
80 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
81 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
82 SetLastError(0xdeadbeef);
83 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
84 CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
85 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
86 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
87 SetLastError(0xdeadbeef);
88 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
89 NULL, NULL);
90 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
91 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
94 static void test_msg_open_to_decode(void)
96 HCRYPTMSG msg;
97 CMSG_STREAM_INFO streamInfo = { 0 };
99 SetLastError(0xdeadbeef);
100 msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
101 ok(!msg && GetLastError() == E_INVALIDARG,
102 "Expected E_INVALIDARG, got %x\n", GetLastError());
104 /* Bad encodings */
105 SetLastError(0xdeadbeef);
106 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
107 ok(!msg && GetLastError() == E_INVALIDARG,
108 "Expected E_INVALIDARG, got %x\n", GetLastError());
109 SetLastError(0xdeadbeef);
110 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
111 ok(!msg && GetLastError() == E_INVALIDARG,
112 "Expected E_INVALIDARG, got %x\n", GetLastError());
114 /* The message type can be explicit... */
115 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
116 NULL);
117 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
118 CryptMsgClose(msg);
119 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 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_HASHED, 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_SIGNED, 0, NULL,
128 NULL);
129 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
130 CryptMsgClose(msg);
131 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
132 CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
133 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
134 CryptMsgClose(msg);
135 /* or implicit.. */
136 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
137 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
138 CryptMsgClose(msg);
139 /* or even invalid. */
140 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
141 NULL);
142 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
143 CryptMsgClose(msg);
144 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
145 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
146 CryptMsgClose(msg);
148 /* And even though the stream info parameter "must be set to NULL" for
149 * CMSG_HASHED, it's still accepted.
151 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
152 &streamInfo);
153 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
154 CryptMsgClose(msg);
157 static void test_msg_get_param(void)
159 BOOL ret;
160 HCRYPTMSG msg;
161 DWORD size, i, value;
162 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
163 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
165 /* Crash
166 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
167 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
168 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
171 /* Decoded messages */
172 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
173 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
174 /* For decoded messages, the type is always available */
175 size = 0;
176 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
177 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
178 size = sizeof(value);
179 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
180 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
181 /* For this (empty) message, the type isn't set */
182 ok(value == 0, "Expected type 0, got %d\n", value);
183 CryptMsgClose(msg);
185 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
186 NULL);
187 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
188 /* For explicitly typed messages, the type is known. */
189 size = sizeof(value);
190 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
191 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
192 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
193 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
195 size = 0;
196 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
197 ok(!ret, "Parameter %d: expected failure\n", i);
199 CryptMsgClose(msg);
201 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
202 NULL);
203 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
204 size = sizeof(value);
205 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
206 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
207 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
208 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
210 size = 0;
211 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
212 ok(!ret, "Parameter %d: expected failure\n", i);
214 CryptMsgClose(msg);
216 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
217 NULL);
218 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
219 size = sizeof(value);
220 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
221 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
222 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
223 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
225 size = 0;
226 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
227 ok(!ret, "Parameter %d: expected failure\n", i);
229 CryptMsgClose(msg);
231 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
232 NULL);
233 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
234 size = sizeof(value);
235 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
236 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
237 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
238 for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
240 size = 0;
241 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
242 ok(!ret, "Parameter %d: expected failure\n", i);
244 CryptMsgClose(msg);
246 /* Explicitly typed messages get their types set, even if they're invalid */
247 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
248 NULL);
249 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
250 size = sizeof(value);
251 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
252 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
253 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
254 CryptMsgClose(msg);
256 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
257 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
258 size = sizeof(value);
259 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
260 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
261 ok(value == 1000, "Expected 1000, got %d\n", value);
262 CryptMsgClose(msg);
265 static void test_msg_close(void)
267 BOOL ret;
268 HCRYPTMSG msg;
270 /* NULL succeeds.. */
271 ret = CryptMsgClose(NULL);
272 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
273 /* but an arbitrary pointer crashes. */
274 if (0)
275 ret = CryptMsgClose((HCRYPTMSG)1);
276 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
277 NULL);
278 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
279 ret = CryptMsgClose(msg);
280 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
283 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
284 const BYTE *expected, DWORD expectedSize)
286 DWORD size;
287 LPBYTE buf;
288 BOOL ret;
290 size = 0xdeadbeef;
291 ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
292 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
293 buf = HeapAlloc(GetProcessHeap(), 0, size);
294 ret = CryptMsgGetParam(msg, param, 0, buf, &size);
295 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
296 ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
297 expectedSize, size);
298 if (size == expectedSize && size)
299 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
300 HeapFree(GetProcessHeap(), 0, buf);
303 static void test_data_msg_open(void)
305 HCRYPTMSG msg;
306 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
307 CMSG_STREAM_INFO streamInfo = { 0 };
308 char oid[] = "1.2.3";
310 /* The data message type takes no additional info */
311 SetLastError(0xdeadbeef);
312 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
313 NULL, NULL);
314 ok(!msg && GetLastError() == E_INVALIDARG,
315 "Expected E_INVALIDARG, got %x\n", GetLastError());
316 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
317 NULL);
318 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
319 CryptMsgClose(msg);
321 /* An empty stream info is allowed. */
322 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
323 &streamInfo);
324 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
325 CryptMsgClose(msg);
327 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
328 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
329 NULL);
330 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
331 CryptMsgClose(msg);
332 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
333 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
334 CMSG_DATA, NULL, oid, NULL);
335 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
336 CryptMsgClose(msg);
337 /* and when a stream info is given, even though you're not supposed to be
338 * able to use anything but szOID_RSA_data when streaming is being used.
340 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
341 CMSG_DATA, NULL, oid, &streamInfo);
342 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
343 CryptMsgClose(msg);
346 static const BYTE msgData[] = { 1, 2, 3, 4 };
348 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
349 BOOL final)
351 return TRUE;
354 static void test_data_msg_update(void)
356 HCRYPTMSG msg;
357 BOOL ret;
358 CMSG_STREAM_INFO streamInfo = { 0 };
360 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
361 NULL);
362 /* Can't update a message that wasn't opened detached with final = FALSE */
363 SetLastError(0xdeadbeef);
364 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
365 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
366 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
367 /* Updating it with final = TRUE succeeds */
368 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
369 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
370 /* Any subsequent update will fail, as the last was final */
371 SetLastError(0xdeadbeef);
372 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
373 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
374 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
375 CryptMsgClose(msg);
377 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
378 NULL);
379 /* Can't update a message with no data */
380 SetLastError(0xdeadbeef);
381 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
382 ok(!ret && GetLastError() == E_INVALIDARG,
383 "Expected E_INVALIDARG, got %x\n", GetLastError());
384 /* Curiously, a valid update will now fail as well, presumably because of
385 * the last (invalid, but final) update.
387 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
388 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
389 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
390 CryptMsgClose(msg);
392 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
393 CMSG_DATA, NULL, NULL, NULL);
394 /* Doesn't appear to be able to update CMSG-DATA with non-final updates */
395 SetLastError(0xdeadbeef);
396 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
397 ok(!ret && GetLastError() == E_INVALIDARG,
398 "Expected E_INVALIDARG, got %x\n", GetLastError());
399 SetLastError(0xdeadbeef);
400 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
401 ok(!ret && GetLastError() == E_INVALIDARG,
402 "Expected E_INVALIDARG, got %x\n", GetLastError());
403 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
404 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
405 CryptMsgClose(msg);
407 /* Calling update after opening with an empty stream info (with a bogus
408 * output function) yields an error:
410 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
411 &streamInfo);
412 SetLastError(0xdeadbeef);
413 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
414 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
415 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
416 CryptMsgClose(msg);
417 /* Calling update with a valid output function succeeds, even if the data
418 * exceeds the size specified in the stream info.
420 streamInfo.pfnStreamOutput = nop_stream_output;
421 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
422 &streamInfo);
423 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
424 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
425 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
426 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
427 CryptMsgClose(msg);
430 static void test_data_msg_get_param(void)
432 HCRYPTMSG msg;
433 DWORD size;
434 BOOL ret;
435 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
437 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
438 NULL);
440 /* Content and bare content are always gettable when not streaming */
441 size = 0;
442 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
443 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
444 size = 0;
445 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
446 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
447 /* But for this type of message, the signer and hash aren't applicable,
448 * and the type isn't available.
450 size = 0;
451 SetLastError(0xdeadbeef);
452 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
453 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
454 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
455 SetLastError(0xdeadbeef);
456 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
457 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
458 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
459 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
460 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
461 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
462 CryptMsgClose(msg);
464 /* Can't get content or bare content when streaming */
465 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
466 NULL, &streamInfo);
467 SetLastError(0xdeadbeef);
468 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
469 ok(!ret && GetLastError() == E_INVALIDARG,
470 "Expected E_INVALIDARG, got %x\n", GetLastError());
471 SetLastError(0xdeadbeef);
472 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
473 ok(!ret && GetLastError() == E_INVALIDARG,
474 "Expected E_INVALIDARG, got %x\n", GetLastError());
475 CryptMsgClose(msg);
478 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
479 static const BYTE dataEmptyContent[] = {
480 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
481 0x04,0x00 };
482 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
483 static const BYTE dataContent[] = {
484 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
485 0x04,0x04,0x01,0x02,0x03,0x04 };
487 struct update_accum
489 DWORD cUpdates;
490 CRYPT_DATA_BLOB *updates;
493 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
494 DWORD cb, BOOL final)
496 struct update_accum *accum = (struct update_accum *)pvArg;
497 BOOL ret = FALSE;
499 if (accum->cUpdates)
500 accum->updates = CryptMemRealloc(accum->updates,
501 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
502 else
503 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
504 if (accum->updates)
506 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
508 blob->pbData = CryptMemAlloc(cb);
509 if (blob->pbData)
511 memcpy(blob->pbData, pb, cb);
512 blob->cbData = cb;
513 ret = TRUE;
515 accum->cUpdates++;
517 return ret;
520 /* The updates of a (bogus) definite-length encoded message */
521 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
522 0x07,0x01,0xa0,0x02,0x04,0x00 };
523 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
524 static CRYPT_DATA_BLOB b1[] = {
525 { sizeof(u1), u1 },
526 { sizeof(u2), u2 },
527 { sizeof(u2), u2 },
529 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
530 /* The updates of a definite-length encoded message */
531 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
532 0x07,0x01,0xa0,0x06,0x04,0x04 };
533 static CRYPT_DATA_BLOB b2[] = {
534 { sizeof(u3), u3 },
535 { sizeof(u2), u2 },
537 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
538 /* The updates of an indefinite-length encoded message */
539 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
540 0x07,0x01,0xa0,0x80,0x24,0x80 };
541 static BYTE u5[] = { 0x04,0x04 };
542 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
543 static CRYPT_DATA_BLOB b3[] = {
544 { sizeof(u4), u4 },
545 { sizeof(u5), u5 },
546 { sizeof(u2), u2 },
547 { sizeof(u5), u5 },
548 { sizeof(u2), u2 },
549 { sizeof(u6), u6 },
551 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
553 static void check_updates(LPCSTR header, const struct update_accum *expected,
554 const struct update_accum *got)
556 DWORD i;
558 ok(expected->cUpdates == got->cUpdates,
559 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
560 got->cUpdates);
561 if (expected->cUpdates == got->cUpdates)
562 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
564 ok(expected->updates[i].cbData == got->updates[i].cbData,
565 "%s, update %d: expected %d bytes, got %d\n", header, i,
566 expected->updates[i].cbData, got->updates[i].cbData);
567 if (expected->updates[i].cbData && expected->updates[i].cbData ==
568 got->updates[i].cbData)
569 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
570 got->updates[i].cbData), "%s, update %d: unexpected value\n",
571 header, i);
575 /* Frees the updates stored in accum */
576 static void free_updates(struct update_accum *accum)
578 DWORD i;
580 for (i = 0; i < accum->cUpdates; i++)
581 CryptMemFree(accum->updates[i].pbData);
582 CryptMemFree(accum->updates);
583 accum->updates = NULL;
584 accum->cUpdates = 0;
587 static void test_data_msg_encoding(void)
589 HCRYPTMSG msg;
590 BOOL ret;
591 static char oid[] = "1.2.3";
592 struct update_accum accum = { 0, NULL };
593 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
595 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
596 NULL);
597 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
598 dataEmptyBareContent, sizeof(dataEmptyBareContent));
599 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
600 sizeof(dataEmptyContent));
601 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
602 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
603 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
604 dataBareContent, sizeof(dataBareContent));
605 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
606 sizeof(dataContent));
607 CryptMsgClose(msg);
608 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
609 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
610 CMSG_DATA, NULL, NULL, NULL);
611 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
612 dataEmptyBareContent, sizeof(dataEmptyBareContent));
613 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
614 sizeof(dataEmptyContent));
615 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
616 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
617 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
618 dataBareContent, sizeof(dataBareContent));
619 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
620 sizeof(dataContent));
621 CryptMsgClose(msg);
622 /* The inner OID is apparently ignored */
623 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
624 NULL);
625 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
626 dataEmptyBareContent, sizeof(dataEmptyBareContent));
627 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
628 dataEmptyContent, sizeof(dataEmptyContent));
629 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
630 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
631 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
632 dataBareContent, sizeof(dataBareContent));
633 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
634 sizeof(dataContent));
635 CryptMsgClose(msg);
636 /* A streaming message is DER encoded if the length is not 0xffffffff, but
637 * curiously, updates aren't validated to make sure they don't exceed the
638 * stated length. (The resulting output will of course fail to decode.)
640 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
641 NULL, &streamInfo);
642 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
643 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
644 CryptMsgClose(msg);
645 check_updates("bogus data message with definite length", &a1, &accum);
646 free_updates(&accum);
647 /* A valid definite-length encoding: */
648 streamInfo.cbContent = sizeof(msgData);
649 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
650 NULL, &streamInfo);
651 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
652 CryptMsgClose(msg);
653 check_updates("data message with definite length", &a2, &accum);
654 free_updates(&accum);
655 /* An indefinite-length encoding: */
656 streamInfo.cbContent = 0xffffffff;
657 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
658 NULL, &streamInfo);
659 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
660 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
661 CryptMsgClose(msg);
662 todo_wine
663 check_updates("data message with indefinite length", &a3, &accum);
664 free_updates(&accum);
667 static void test_data_msg(void)
669 test_data_msg_open();
670 test_data_msg_update();
671 test_data_msg_get_param();
672 test_data_msg_encoding();
675 static void test_hash_msg_open(void)
677 HCRYPTMSG msg;
678 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
679 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
681 SetLastError(0xdeadbeef);
682 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
683 NULL, NULL);
684 ok(!msg && GetLastError() == E_INVALIDARG,
685 "Expected E_INVALIDARG, got %x\n", GetLastError());
686 hashInfo.cbSize = sizeof(hashInfo);
687 SetLastError(0xdeadbeef);
688 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
689 NULL, NULL);
690 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
691 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
692 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
693 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
694 NULL, NULL);
695 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
696 CryptMsgClose(msg);
697 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
698 CMSG_HASHED, &hashInfo, NULL, NULL);
699 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
700 CryptMsgClose(msg);
701 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
702 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
703 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
704 CryptMsgClose(msg);
707 static void test_hash_msg_update(void)
709 HCRYPTMSG msg;
710 BOOL ret;
711 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
712 { oid_rsa_md5, { 0, NULL } }, NULL };
713 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
715 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
716 CMSG_HASHED, &hashInfo, NULL, NULL);
717 /* Detached hashed messages opened in non-streaming mode allow non-final
718 * updates..
720 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
721 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
722 /* including non-final updates with no data.. */
723 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
724 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
725 /* and final updates with no data. */
726 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
727 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
728 /* But no updates are allowed after the final update. */
729 SetLastError(0xdeadbeef);
730 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
731 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
732 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
733 SetLastError(0xdeadbeef);
734 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
735 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
736 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
737 CryptMsgClose(msg);
738 /* Non-detached messages, in contrast, don't allow non-final updates in
739 * non-streaming mode.
741 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
742 NULL, NULL);
743 SetLastError(0xdeadbeef);
744 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
745 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
746 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
747 /* Final updates (including empty ones) are allowed. */
748 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
749 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
750 CryptMsgClose(msg);
751 /* And, of course, streaming mode allows non-final updates */
752 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
753 NULL, &streamInfo);
754 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
755 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
756 CryptMsgClose(msg);
757 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
758 * to be a bug, it isn't actually used - see encoding tests.)
760 streamInfo.pfnStreamOutput = NULL;
761 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
762 NULL, &streamInfo);
763 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
764 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
765 CryptMsgClose(msg);
768 static const BYTE emptyHashParam[] = {
769 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
770 0x7e };
772 static void test_hash_msg_get_param(void)
774 HCRYPTMSG msg;
775 BOOL ret;
776 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
777 { oid_rsa_md5, { 0, NULL } }, NULL };
778 DWORD size, value;
779 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
780 BYTE buf[16];
782 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
783 NULL, NULL);
784 /* Content and bare content are always gettable for non-streamed messages */
785 size = 0;
786 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
787 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
788 size = 0;
789 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
790 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
791 /* For an encoded hash message, the hash data aren't available */
792 SetLastError(0xdeadbeef);
793 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
794 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
795 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
796 /* The hash is also available. */
797 size = 0;
798 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
799 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
800 ok(size == sizeof(buf), "Unexpected size %d\n", size);
801 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
802 if (size == sizeof(buf))
803 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
804 /* By getting the hash, further updates are not allowed */
805 SetLastError(0xdeadbeef);
806 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
807 ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
808 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
809 /* Even after a final update, the hash data aren't available */
810 SetLastError(0xdeadbeef);
811 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
812 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
813 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
814 /* The version is also available, and should be zero for this message. */
815 size = 0;
816 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
817 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
818 size = sizeof(value);
819 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
820 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
821 ok(value == 0, "Expected version 0, got %d\n", value);
822 /* As usual, the type isn't available. */
823 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
824 ok(!ret, "Expected failure\n");
825 CryptMsgClose(msg);
827 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
828 NULL, &streamInfo);
829 /* Streamed messages don't allow you to get the content or bare content. */
830 SetLastError(0xdeadbeef);
831 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
832 ok(!ret && GetLastError() == E_INVALIDARG,
833 "Expected E_INVALIDARG, got %x\n", GetLastError());
834 SetLastError(0xdeadbeef);
835 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
836 ok(!ret && GetLastError() == E_INVALIDARG,
837 "Expected E_INVALIDARG, got %x\n", GetLastError());
838 /* The hash is still available. */
839 size = 0;
840 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
841 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
842 ok(size == sizeof(buf), "Unexpected size %d\n", size);
843 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
844 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
845 if (size == sizeof(buf))
846 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
847 /* After updating the hash, further updates aren't allowed on streamed
848 * messages either.
850 SetLastError(0xdeadbeef);
851 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
852 ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
853 "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
854 CryptMsgClose(msg);
857 static const BYTE hashEmptyBareContent[] = {
858 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
859 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
860 static const BYTE hashEmptyContent[] = {
861 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
862 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
863 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
864 static const BYTE hashBareContent[] = {
865 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
866 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
867 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
868 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
869 static const BYTE hashContent[] = {
870 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
871 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
872 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
873 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
874 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
876 static const BYTE detachedHashNonFinalBareContent[] = {
877 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
878 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
879 0x07,0x01,0x04,0x00 };
880 static const BYTE detachedHashNonFinalContent[] = {
881 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
882 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
883 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
884 0x07,0x01,0x04,0x00 };
885 static const BYTE detachedHashBareContent[] = {
886 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
887 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
888 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
889 0x9d,0x2a,0x8f,0x26,0x2f };
890 static const BYTE detachedHashContent[] = {
891 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
892 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
893 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
894 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
895 0x9d,0x2a,0x8f,0x26,0x2f };
897 static void test_hash_msg_encoding(void)
899 HCRYPTMSG msg;
900 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
901 BOOL ret;
902 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
903 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
905 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
906 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
907 NULL, NULL);
908 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
909 hashEmptyBareContent, sizeof(hashEmptyBareContent));
910 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
911 hashEmptyContent, sizeof(hashEmptyContent));
912 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
913 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
914 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
915 hashBareContent, sizeof(hashBareContent));
916 check_param("hash content", msg, CMSG_CONTENT_PARAM,
917 hashContent, sizeof(hashContent));
918 CryptMsgClose(msg);
919 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
920 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
921 CMSG_HASHED, &hashInfo, NULL, NULL);
922 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
923 hashEmptyBareContent, sizeof(hashEmptyBareContent));
924 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
925 hashEmptyContent, sizeof(hashEmptyContent));
926 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
927 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
928 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
929 hashBareContent, sizeof(hashBareContent));
930 check_param("hash content", msg, CMSG_CONTENT_PARAM,
931 hashContent, sizeof(hashContent));
932 CryptMsgClose(msg);
933 /* Same test, but with CMSG_DETACHED_FLAG set */
934 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
935 CMSG_HASHED, &hashInfo, NULL, NULL);
936 check_param("detached hash empty bare content", msg,
937 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
938 sizeof(hashEmptyBareContent));
939 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
940 hashEmptyContent, sizeof(hashEmptyContent));
941 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
942 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
943 check_param("detached hash not final bare content", msg,
944 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
945 sizeof(detachedHashNonFinalBareContent));
946 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
947 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
948 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
949 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
950 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
951 detachedHashBareContent, sizeof(detachedHashBareContent));
952 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
953 detachedHashContent, sizeof(detachedHashContent));
954 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
955 detachedHashBareContent, sizeof(detachedHashBareContent));
956 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
957 detachedHashContent, sizeof(detachedHashContent));
958 CryptMsgClose(msg);
959 /* In what appears to be a bug, streamed updates to hash messages don't
960 * call the output function.
962 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
963 NULL, &streamInfo);
964 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
965 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
966 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
967 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
968 CryptMsgClose(msg);
969 check_updates("empty hash message", &empty_accum, &accum);
970 free_updates(&accum);
972 streamInfo.cbContent = sizeof(msgData);
973 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
974 NULL, &streamInfo);
975 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
976 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
977 CryptMsgClose(msg);
978 check_updates("hash message", &empty_accum, &accum);
979 free_updates(&accum);
981 streamInfo.cbContent = sizeof(msgData);
982 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
983 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
984 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
985 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
986 CryptMsgClose(msg);
987 check_updates("detached hash message", &empty_accum, &accum);
988 free_updates(&accum);
991 static void test_hash_msg(void)
993 test_hash_msg_open();
994 test_hash_msg_update();
995 test_hash_msg_get_param();
996 test_hash_msg_encoding();
999 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1000 'm','p',0 };
1001 static BYTE serialNum[] = { 1 };
1002 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1003 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1005 static void test_signed_msg_open(void)
1007 HCRYPTMSG msg;
1008 BOOL ret;
1009 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1010 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1011 CERT_INFO certInfo = { 0 };
1013 SetLastError(0xdeadbeef);
1014 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1015 NULL, NULL);
1016 ok(!msg && GetLastError() == E_INVALIDARG,
1017 "Expected E_INVALIDARG, got %x\n", GetLastError());
1018 signInfo.cbSize = sizeof(signInfo);
1019 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1020 NULL, NULL);
1021 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1022 CryptMsgClose(msg);
1024 signInfo.cSigners = 1;
1025 signInfo.rgSigners = &signer;
1026 /* With signer.pCertInfo unset, attempting to open this message this
1027 * crashes.
1029 signer.pCertInfo = &certInfo;
1030 /* The cert info must contain a serial number and an issuer. */
1031 SetLastError(0xdeadbeef);
1032 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1033 NULL, NULL);
1034 ok(!msg && GetLastError() == E_INVALIDARG,
1035 "Expected E_INVALIDARG, got %x\n", GetLastError());
1036 certInfo.SerialNumber.cbData = sizeof(serialNum);
1037 certInfo.SerialNumber.pbData = serialNum;
1038 SetLastError(0xdeadbeef);
1039 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1040 NULL, NULL);
1041 ok(!msg && GetLastError() == E_INVALIDARG,
1042 "Expected E_INVALIDARG, got %x\n", GetLastError());
1043 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1044 certInfo.Issuer.pbData = encodedCommonName;
1045 SetLastError(0xdeadbeef);
1046 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1047 NULL, NULL);
1048 ok(!msg && GetLastError() == E_INVALIDARG,
1049 "Expected E_INVALIDARG, got %x\n", GetLastError());
1051 /* The signer's hCryptProv must be set to something. Whether it's usable
1052 * or not will be checked after the hash algorithm is checked (see next
1053 * test.)
1055 signer.hCryptProv = 1;
1056 SetLastError(0xdeadbeef);
1057 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1058 NULL, NULL);
1059 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1060 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1061 /* The signer's hash algorithm must also be set. */
1062 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1063 SetLastError(0xdeadbeef);
1064 /* Crashes in advapi32 in wine, don't do it */
1065 if (0) {
1066 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1067 &signInfo, NULL, NULL);
1068 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1069 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1071 /* The signer's hCryptProv must also be valid. */
1072 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1073 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1074 if (!ret && GetLastError() == NTE_EXISTS)
1075 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1076 PROV_RSA_FULL, 0);
1077 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1078 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1079 NULL, NULL);
1080 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1081 CryptMsgClose(msg);
1083 CryptReleaseContext(signer.hCryptProv, 0);
1084 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1085 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1088 static const BYTE privKey[] = {
1089 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1090 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1091 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1092 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1093 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1094 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1095 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1096 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1097 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1098 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1099 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1100 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1101 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1102 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1103 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1104 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1105 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1106 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1107 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1108 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1109 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1110 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1111 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1112 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1114 static void test_signed_msg_update(void)
1116 HCRYPTMSG msg;
1117 BOOL ret;
1118 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1119 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1120 CERT_INFO certInfo = { 0 };
1121 HCRYPTKEY key;
1123 certInfo.SerialNumber.cbData = sizeof(serialNum);
1124 certInfo.SerialNumber.pbData = serialNum;
1125 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1126 certInfo.Issuer.pbData = encodedCommonName;
1127 signer.pCertInfo = &certInfo;
1128 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1129 signInfo.cSigners = 1;
1130 signInfo.rgSigners = &signer;
1131 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1132 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1133 if (!ret && GetLastError() == NTE_EXISTS)
1134 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1135 PROV_RSA_FULL, 0);
1136 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1137 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1138 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1139 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1140 /* Detached CMSG_SIGNED allows non-final updates. */
1141 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1142 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1143 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1144 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1145 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1146 /* The final update requires a private key in the hCryptProv, in order to
1147 * generate the signature.
1149 SetLastError(0xdeadbeef);
1150 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1151 ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1152 GetLastError() == NTE_NO_KEY),
1153 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1154 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1155 0, 0, &key);
1156 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1157 /* The final update should be able to succeed now that a key exists, but
1158 * the previous (invalid) final update prevents it.
1160 SetLastError(0xdeadbeef);
1161 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1162 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1163 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1164 CryptMsgClose(msg);
1166 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1167 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1168 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1169 /* Detached CMSG_SIGNED allows non-final updates. */
1170 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1171 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1172 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1173 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1174 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1175 /* Now that the private key exists, the final update can succeed (even
1176 * with no data.)
1178 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1179 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1180 /* But no updates are allowed after the final update. */
1181 SetLastError(0xdeadbeef);
1182 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1183 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1184 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1185 SetLastError(0xdeadbeef);
1186 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1187 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1188 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1189 CryptMsgClose(msg);
1191 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1192 NULL, NULL);
1193 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1194 /* Non-detached messages don't allow non-final updates.. */
1195 SetLastError(0xdeadbeef);
1196 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1197 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1198 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1199 /* but they do allow final ones. */
1200 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1201 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1202 CryptMsgClose(msg);
1203 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1204 NULL, NULL);
1205 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1206 /* They also allow final updates with no data. */
1207 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1208 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1209 CryptMsgClose(msg);
1211 CryptDestroyKey(key);
1212 CryptReleaseContext(signer.hCryptProv, 0);
1213 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1214 CRYPT_DELETEKEYSET);
1217 static const BYTE signedEmptyBareContent[] = {
1218 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1219 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1220 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1221 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1222 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1223 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1224 static const BYTE signedEmptyContent[] = {
1225 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1226 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1227 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1228 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1229 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1230 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1231 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1232 static const BYTE detachedSignedBareContent[] = {
1233 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1234 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1235 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1236 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1237 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1238 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1239 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1240 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1241 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1242 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1243 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1244 static const BYTE detachedSignedContent[] = {
1245 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1246 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1247 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1248 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1249 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1250 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1251 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1252 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1253 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1254 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1255 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1256 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1257 static const BYTE signedBareContent[] = {
1258 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1259 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1260 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1261 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1262 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1263 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1264 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1265 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1266 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1267 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1268 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1269 static const BYTE signedContent[] = {
1270 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1271 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1272 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1273 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1274 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1275 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1276 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1277 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1278 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1279 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1280 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1281 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1282 0x0d };
1283 static const BYTE signedHash[] = {
1284 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1285 0x2f };
1286 static const BYTE signedEncodedSigner[] = {
1287 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1288 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1289 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1290 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1291 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1292 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1293 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1294 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1295 static const BYTE signedWithAuthAttrsBareContent[] = {
1296 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1297 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1298 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1299 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1300 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1301 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1302 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1303 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1304 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1305 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1306 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1307 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1308 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1309 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1310 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1311 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1312 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1313 0xff,0xc6,0x33,0x63,0x34 };
1314 static BYTE cert[] = {
1315 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1316 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1317 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1318 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1319 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1320 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1321 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1322 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1323 0xff,0x02,0x01,0x01 };
1324 static BYTE v1CertWithPubKey[] = {
1325 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1326 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1327 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1328 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1329 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1330 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1331 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1332 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1333 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1334 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1335 0x01,0x01 };
1336 static const BYTE signedWithCertEmptyBareContent[] = {
1337 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1338 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1339 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1340 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1341 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1342 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1343 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1344 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1345 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1346 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1347 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1348 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1349 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1350 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1351 static const BYTE signedWithCertBareContent[] = {
1352 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1353 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1354 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1355 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1356 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1357 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1358 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1359 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1360 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1361 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1362 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1363 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1364 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1365 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1366 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1367 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1368 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1369 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1370 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1371 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1372 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1373 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1374 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1375 0x30,0x30,0x30,0x30,0x5a };
1376 static const BYTE signedWithCrlEmptyBareContent[] = {
1377 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1378 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1379 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1380 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1381 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1382 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1383 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1384 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1385 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1386 static const BYTE signedWithCrlBareContent[] = {
1387 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1388 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1389 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1390 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1391 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1392 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1393 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1394 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1395 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1396 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1397 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1398 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1399 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1400 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1401 0xa8,0x0d };
1402 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1403 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1404 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1405 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1406 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1407 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1408 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1409 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1410 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1411 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1412 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1413 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1414 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1415 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1416 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1417 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1418 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1419 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1420 0x04,0x00 };
1421 static const BYTE signedWithCertAndCrlBareContent[] = {
1422 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1423 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1424 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1425 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1426 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1427 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1428 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1429 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1430 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1431 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1432 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1433 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1434 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1435 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1436 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1437 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1438 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1439 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1440 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1441 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1442 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1443 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1444 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1445 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1446 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1447 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1448 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1449 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1450 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1451 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1452 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1453 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1454 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1455 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1456 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1457 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1458 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1459 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1460 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1461 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1462 static BYTE v1CertWithValidPubKey[] = {
1463 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1464 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1465 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1466 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1467 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1468 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1469 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1470 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1471 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1472 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1473 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1474 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1475 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1476 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1477 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1478 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1479 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1480 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1481 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1482 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1483 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1484 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1485 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1486 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1487 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1488 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1489 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1490 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1491 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1492 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1493 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1494 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1495 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1496 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1497 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1498 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1499 0x00 };
1500 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1501 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1502 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1503 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1504 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1505 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1506 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1507 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1508 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1509 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1510 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1511 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1512 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1513 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1514 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1515 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1516 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1517 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1518 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1519 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1520 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1521 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1522 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1523 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1524 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1525 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1526 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1527 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1529 static void test_signed_msg_encoding(void)
1531 HCRYPTMSG msg;
1532 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1533 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1534 CERT_INFO certInfo = { 0 };
1535 CERT_BLOB encodedCert = { sizeof(cert), cert };
1536 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1537 char oid_common_name[] = szOID_COMMON_NAME;
1538 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1539 encodedCommonName };
1540 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1541 BOOL ret;
1542 HCRYPTKEY key;
1543 DWORD size;
1545 certInfo.SerialNumber.cbData = sizeof(serialNum);
1546 certInfo.SerialNumber.pbData = serialNum;
1547 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1548 certInfo.Issuer.pbData = encodedCommonName;
1549 signer.pCertInfo = &certInfo;
1550 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1551 signInfo.cSigners = 1;
1552 signInfo.rgSigners = &signer;
1553 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1554 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1555 if (!ret && GetLastError() == NTE_EXISTS)
1556 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1557 PROV_RSA_FULL, 0);
1558 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1559 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1560 0, 0, &key);
1561 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1563 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1564 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1565 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1567 check_param("detached signed empty bare content", msg,
1568 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1569 sizeof(signedEmptyBareContent));
1570 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1571 signedEmptyContent, sizeof(signedEmptyContent));
1572 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1573 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1574 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1575 signedHash, sizeof(signedHash));
1576 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1577 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1578 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1579 detachedSignedContent, sizeof(detachedSignedContent));
1580 SetLastError(0xdeadbeef);
1581 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1582 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1583 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1584 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1585 signedEncodedSigner, sizeof(signedEncodedSigner));
1587 CryptMsgClose(msg);
1589 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1590 NULL, NULL);
1591 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1593 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1594 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1595 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1596 signedEmptyContent, sizeof(signedEmptyContent));
1597 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1598 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1599 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1600 signedBareContent, sizeof(signedBareContent));
1601 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1602 signedContent, sizeof(signedContent));
1604 CryptMsgClose(msg);
1606 signer.cAuthAttr = 1;
1607 signer.rgAuthAttr = &attr;
1608 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1609 NULL, NULL);
1610 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1612 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1613 check_param("signed with auth attrs bare content", msg,
1614 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1615 sizeof(signedWithAuthAttrsBareContent));
1617 CryptMsgClose(msg);
1619 signer.cAuthAttr = 0;
1620 signInfo.rgCertEncoded = &encodedCert;
1621 signInfo.cCertEncoded = 1;
1622 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1623 NULL, NULL);
1624 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1626 check_param("signed with cert empty bare content", msg,
1627 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1628 sizeof(signedWithCertEmptyBareContent));
1629 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1630 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1631 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1632 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1634 CryptMsgClose(msg);
1636 signInfo.cCertEncoded = 0;
1637 signInfo.rgCrlEncoded = &encodedCrl;
1638 signInfo.cCrlEncoded = 1;
1639 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1640 NULL, NULL);
1641 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1643 check_param("signed with crl empty bare content", msg,
1644 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1645 sizeof(signedWithCrlEmptyBareContent));
1646 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1647 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1648 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1649 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1651 CryptMsgClose(msg);
1653 signInfo.cCertEncoded = 1;
1654 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1655 NULL, NULL);
1656 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1658 check_param("signed with cert and crl empty bare content", msg,
1659 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1660 sizeof(signedWithCertAndCrlEmptyBareContent));
1661 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1662 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1663 check_param("signed with cert and crl bare content", msg,
1664 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1665 sizeof(signedWithCertAndCrlBareContent));
1667 CryptMsgClose(msg);
1669 /* Test with a cert with a (bogus) public key */
1670 signInfo.cCrlEncoded = 0;
1671 encodedCert.cbData = sizeof(v1CertWithPubKey);
1672 encodedCert.pbData = v1CertWithPubKey;
1673 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1674 NULL, NULL);
1675 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1676 check_param("signedWithCertWithPubKeyBareContent", msg,
1677 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1678 sizeof(signedWithCertWithPubKeyBareContent));
1679 CryptMsgClose(msg);
1681 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1682 encodedCert.pbData = v1CertWithValidPubKey;
1683 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1684 NULL, NULL);
1685 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1686 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1687 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1688 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1689 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1690 check_param("signedWithCertWithValidPubKeyContent", msg,
1691 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1692 sizeof(signedWithCertWithValidPubKeyContent));
1693 CryptMsgClose(msg);
1695 CryptDestroyKey(key);
1696 CryptReleaseContext(signer.hCryptProv, 0);
1697 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1698 CRYPT_DELETEKEYSET);
1701 static void test_signed_msg_get_param(void)
1703 BOOL ret;
1704 HCRYPTMSG msg;
1705 DWORD size, value = 0;
1706 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1707 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1708 CERT_INFO certInfo = { 0 };
1710 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1711 NULL, NULL);
1712 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1714 /* Content and bare content are always gettable */
1715 size = 0;
1716 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1717 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1718 size = 0;
1719 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1720 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1721 /* For "signed" messages, so is the version. */
1722 size = 0;
1723 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1724 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1725 size = sizeof(value);
1726 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1727 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1728 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1729 /* But for this message, with no signers, the hash and signer aren't
1730 * available.
1732 size = 0;
1733 SetLastError(0xdeadbeef);
1734 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1735 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1736 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1737 SetLastError(0xdeadbeef);
1738 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1739 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1740 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1741 /* As usual, the type isn't available. */
1742 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1743 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1744 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1746 CryptMsgClose(msg);
1748 certInfo.SerialNumber.cbData = sizeof(serialNum);
1749 certInfo.SerialNumber.pbData = serialNum;
1750 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1751 certInfo.Issuer.pbData = encodedCommonName;
1752 signer.pCertInfo = &certInfo;
1753 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1754 signInfo.cSigners = 1;
1755 signInfo.rgSigners = &signer;
1756 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1757 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1758 if (!ret && GetLastError() == NTE_EXISTS)
1759 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1760 PROV_RSA_FULL, 0);
1761 ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1762 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1763 NULL, NULL);
1764 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1766 /* This message, with one signer, has the hash and signer for index 0
1767 * available, but not for other indexes.
1769 size = 0;
1770 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1771 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1772 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1773 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1774 size = 0;
1775 SetLastError(0xdeadbeef);
1776 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1777 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1778 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1779 SetLastError(0xdeadbeef);
1780 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1781 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1782 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1783 /* As usual, the type isn't available. */
1784 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1785 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1786 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1788 CryptMsgClose(msg);
1790 CryptReleaseContext(signer.hCryptProv, 0);
1791 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1792 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1795 static void test_signed_msg(void)
1797 test_signed_msg_open();
1798 test_signed_msg_update();
1799 test_signed_msg_encoding();
1800 test_signed_msg_get_param();
1803 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1804 static const struct update_accum a4 = { 1, &b4 };
1806 static const BYTE bogusOIDContent[] = {
1807 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1808 0x04,0x00 };
1809 static const BYTE bogusHashContent[] = {
1810 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1811 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1812 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1813 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1814 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1816 static void test_decode_msg_update(void)
1818 HCRYPTMSG msg;
1819 BOOL ret;
1820 CMSG_STREAM_INFO streamInfo = { 0 };
1821 DWORD i;
1822 struct update_accum accum = { 0, NULL };
1824 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1825 /* Update with a full message in a final update */
1826 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1827 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1828 /* Can't update after a final update */
1829 SetLastError(0xdeadbeef);
1830 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1831 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1832 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1833 CryptMsgClose(msg);
1835 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1836 /* Can't send a non-final update without streaming */
1837 SetLastError(0xdeadbeef);
1838 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1839 FALSE);
1840 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1841 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1842 /* A subsequent final update succeeds */
1843 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1844 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1845 CryptMsgClose(msg);
1847 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1848 /* Updating a message that has a NULL stream callback fails */
1849 SetLastError(0xdeadbeef);
1850 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1851 FALSE);
1852 todo_wine
1853 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1854 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1855 /* Changing the callback pointer after the fact yields the same error (so
1856 * the message must copy the stream info, not just store a pointer to it)
1858 streamInfo.pfnStreamOutput = nop_stream_output;
1859 SetLastError(0xdeadbeef);
1860 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1861 FALSE);
1862 todo_wine
1863 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1864 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1865 CryptMsgClose(msg);
1867 /* Empty non-final updates are allowed when streaming.. */
1868 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1869 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1870 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1871 /* but final updates aren't when not enough data has been received. */
1872 SetLastError(0xdeadbeef);
1873 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1874 todo_wine
1875 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1876 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1877 CryptMsgClose(msg);
1879 /* Updating the message byte by byte is legal */
1880 streamInfo.pfnStreamOutput = accumulating_stream_output;
1881 streamInfo.pvArg = &accum;
1882 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1883 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1884 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1885 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1886 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1887 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1888 CryptMsgClose(msg);
1889 todo_wine
1890 check_updates("byte-by-byte empty content", &a4, &accum);
1891 free_updates(&accum);
1893 /* Decoding bogus content fails in non-streaming mode.. */
1894 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1895 SetLastError(0xdeadbeef);
1896 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1897 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1898 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1899 CryptMsgClose(msg);
1900 /* and as the final update in streaming mode.. */
1901 streamInfo.pfnStreamOutput = nop_stream_output;
1902 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1903 SetLastError(0xdeadbeef);
1904 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1905 todo_wine
1906 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1907 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1908 CryptMsgClose(msg);
1909 /* and even as a non-final update in streaming mode. */
1910 streamInfo.pfnStreamOutput = nop_stream_output;
1911 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1912 SetLastError(0xdeadbeef);
1913 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1914 todo_wine
1915 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1916 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1917 CryptMsgClose(msg);
1919 /* An empty message can be opened with indetermined type.. */
1920 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1921 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1922 TRUE);
1923 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1924 /* but decoding it as an explicitly typed message fails. */
1925 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1926 NULL);
1927 SetLastError(0xdeadbeef);
1928 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1929 TRUE);
1930 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1931 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1932 CryptMsgClose(msg);
1933 /* On the other hand, decoding the bare content of an empty message fails
1934 * with unspecified type..
1936 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1937 SetLastError(0xdeadbeef);
1938 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1939 sizeof(dataEmptyBareContent), TRUE);
1940 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1941 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1942 CryptMsgClose(msg);
1943 /* but succeeds with explicit type. */
1944 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1945 NULL);
1946 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1947 sizeof(dataEmptyBareContent), TRUE);
1948 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1949 CryptMsgClose(msg);
1951 /* Decoding valid content with an unsupported OID fails */
1952 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1953 SetLastError(0xdeadbeef);
1954 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
1955 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1956 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1957 CryptMsgClose(msg);
1959 /* Similarly, opening an empty hash with unspecified type succeeds.. */
1960 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1961 SetLastError(0xdeadbeef);
1962 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1963 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1964 CryptMsgClose(msg);
1965 /* while with specified type it fails. */
1966 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1967 NULL);
1968 SetLastError(0xdeadbeef);
1969 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1970 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1971 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1972 CryptMsgClose(msg);
1973 /* On the other hand, decoding the bare content of an empty hash message
1974 * fails with unspecified type..
1976 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1977 SetLastError(0xdeadbeef);
1978 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1979 sizeof(hashEmptyBareContent), TRUE);
1980 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1981 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1982 CryptMsgClose(msg);
1983 /* but succeeds with explicit type. */
1984 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1985 NULL);
1986 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1987 sizeof(hashEmptyBareContent), TRUE);
1988 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1989 CryptMsgClose(msg);
1991 /* And again, opening a (non-empty) hash message with unspecified type
1992 * succeeds..
1994 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1995 SetLastError(0xdeadbeef);
1996 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
1997 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1998 CryptMsgClose(msg);
1999 /* while with specified type it fails.. */
2000 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2001 NULL);
2002 SetLastError(0xdeadbeef);
2003 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2004 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2005 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2006 CryptMsgClose(msg);
2007 /* and decoding the bare content of a non-empty hash message fails with
2008 * unspecified type..
2010 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2011 SetLastError(0xdeadbeef);
2012 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2013 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2014 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2015 CryptMsgClose(msg);
2016 /* but succeeds with explicit type. */
2017 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2018 NULL);
2019 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2020 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2021 CryptMsgClose(msg);
2023 /* Opening a (non-empty) hash message with unspecified type and a bogus
2024 * hash value succeeds..
2026 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2027 SetLastError(0xdeadbeef);
2028 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2029 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2030 CryptMsgClose(msg);
2032 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2033 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2034 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2035 CryptMsgClose(msg);
2036 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2037 SetLastError(0xdeadbeef);
2038 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2039 sizeof(signedWithCertAndCrlBareContent), TRUE);
2040 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2041 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2042 CryptMsgClose(msg);
2043 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2044 NULL);
2045 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2046 sizeof(signedWithCertAndCrlBareContent), TRUE);
2047 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2048 CryptMsgClose(msg);
2051 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2052 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2054 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2055 const CMSG_SIGNER_INFO *expected)
2057 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2058 expected->dwVersion, got->dwVersion);
2059 ok(got->Issuer.cbData == expected->Issuer.cbData,
2060 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2061 got->Issuer.cbData);
2062 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2063 "Unexpected issuer\n");
2064 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2065 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2066 got->SerialNumber.cbData);
2067 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2068 got->SerialNumber.cbData), "Unexpected serial number\n");
2069 /* FIXME: check more things */
2072 static const BYTE signedWithCertAndCrlComputedHash[] = {
2073 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2074 0x2f };
2076 static void test_decode_msg_get_param(void)
2078 HCRYPTMSG msg;
2079 BOOL ret;
2080 DWORD size = 0, value;
2081 LPBYTE buf;
2083 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2084 SetLastError(0xdeadbeef);
2085 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2086 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2087 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2088 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2089 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2090 sizeof(msgData));
2091 CryptMsgClose(msg);
2093 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2094 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2095 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2096 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2097 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2098 emptyHashParam, sizeof(emptyHashParam));
2099 CryptMsgClose(msg);
2100 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2101 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2102 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2103 sizeof(msgData));
2104 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2105 sizeof(hashParam));
2106 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2107 hashParam, sizeof(hashParam));
2108 /* Curiously, getting the hash of index 1 succeeds, even though there's
2109 * only one hash.
2111 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2112 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2113 buf = CryptMemAlloc(size);
2114 if (buf)
2116 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2117 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2118 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2119 CryptMemFree(buf);
2121 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2122 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2123 value = CMSG_HASHED_DATA_V0;
2124 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2125 sizeof(value));
2126 CryptMsgClose(msg);
2128 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2129 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2130 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2131 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2132 sizeof(msgData));
2133 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2134 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2135 size = sizeof(value);
2136 value = 2112;
2137 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2138 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2139 ok(value == 1, "Expected 1 signer, got %d\n", value);
2140 size = 0;
2141 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2142 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2143 if (ret)
2144 buf = CryptMemAlloc(size);
2145 else
2146 buf = NULL;
2147 if (buf)
2149 CMSG_SIGNER_INFO signer = { 0 };
2151 signer.dwVersion = 1;
2152 signer.Issuer.cbData = sizeof(encodedCommonName);
2153 signer.Issuer.pbData = encodedCommonName;
2154 signer.SerialNumber.cbData = sizeof(serialNum);
2155 signer.SerialNumber.pbData = serialNum;
2156 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2157 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2158 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2159 CryptMemFree(buf);
2161 /* index is ignored when getting signer count */
2162 size = sizeof(value);
2163 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2164 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2165 ok(value == 1, "Expected 1 signer, got %d\n", value);
2166 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2167 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2168 ok(value == 0, "Expected 0 certs, got %d\n", value);
2169 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2170 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2171 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2172 CryptMsgClose(msg);
2173 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2174 NULL);
2175 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2176 sizeof(signedWithCertAndCrlBareContent), TRUE);
2177 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2178 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2179 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2180 ok(value == 1, "Expected 1 cert, got %d\n", value);
2181 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2182 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2183 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2184 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2185 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2186 check_param("signed with cert and CRL computed hash", msg,
2187 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2188 sizeof(signedWithCertAndCrlComputedHash));
2189 CryptMsgClose(msg);
2192 static void test_decode_msg(void)
2194 test_decode_msg_update();
2195 test_decode_msg_get_param();
2198 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2199 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2200 static BYTE encodedPubKey[] = {
2201 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2202 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2203 0x0d,0x0e,0x0f };
2204 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2205 static BYTE mod_encoded[] = {
2206 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2207 0x01,0x00,0x01 };
2209 static void test_msg_control(void)
2211 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2212 BOOL ret;
2213 HCRYPTMSG msg;
2214 DWORD i;
2215 CERT_INFO certInfo = { 0 };
2216 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2217 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2218 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2220 /* Crashes
2221 ret = CryptMsgControl(NULL, 0, 0, NULL);
2224 /* Data encode messages don't allow any sort of control.. */
2225 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2226 NULL);
2227 /* either with no prior update.. */
2228 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2230 SetLastError(0xdeadbeef);
2231 ret = CryptMsgControl(msg, 0, i, NULL);
2232 ok(!ret && GetLastError() == E_INVALIDARG,
2233 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2235 /* or after an update. */
2236 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2238 SetLastError(0xdeadbeef);
2239 ret = CryptMsgControl(msg, 0, i, NULL);
2240 ok(!ret && GetLastError() == E_INVALIDARG,
2241 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2243 CryptMsgClose(msg);
2245 /* Hash encode messages don't allow any sort of control.. */
2246 hashInfo.cbSize = sizeof(hashInfo);
2247 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2248 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2249 NULL, NULL);
2250 /* either with no prior update.. */
2251 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2253 SetLastError(0xdeadbeef);
2254 ret = CryptMsgControl(msg, 0, i, NULL);
2255 ok(!ret && GetLastError() == E_INVALIDARG,
2256 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2258 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2259 /* or after an update. */
2260 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2262 SetLastError(0xdeadbeef);
2263 ret = CryptMsgControl(msg, 0, i, NULL);
2264 ok(!ret && GetLastError() == E_INVALIDARG,
2265 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2267 CryptMsgClose(msg);
2269 /* Signed encode messages likewise don't allow any sort of control.. */
2270 signInfo.cbSize = sizeof(signInfo);
2271 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2272 NULL, NULL);
2273 /* either before an update.. */
2274 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2276 SetLastError(0xdeadbeef);
2277 ret = CryptMsgControl(msg, 0, i, NULL);
2278 ok(!ret && GetLastError() == E_INVALIDARG,
2279 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2281 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2282 /* or after an update. */
2283 for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2285 SetLastError(0xdeadbeef);
2286 ret = CryptMsgControl(msg, 0, i, NULL);
2287 ok(!ret && GetLastError() == E_INVALIDARG,
2288 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2290 CryptMsgClose(msg);
2292 /* Decode messages behave a bit differently. */
2293 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2294 /* Bad control type */
2295 SetLastError(0xdeadbeef);
2296 ret = CryptMsgControl(msg, 0, 0, NULL);
2297 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2298 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2299 SetLastError(0xdeadbeef);
2300 ret = CryptMsgControl(msg, 1, 0, NULL);
2301 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2302 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2303 /* Can't verify the hash of an indeterminate-type message */
2304 SetLastError(0xdeadbeef);
2305 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2306 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2307 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2308 /* Crashes
2309 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2311 /* Can't decrypt an indeterminate-type message */
2312 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2313 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2314 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2315 CryptMsgClose(msg);
2317 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2318 NULL);
2319 /* Can't verify the hash of an empty message */
2320 SetLastError(0xdeadbeef);
2321 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2322 todo_wine
2323 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2324 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2325 /* Crashes
2326 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2328 /* Can't verify the signature of a hash message */
2329 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2330 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2331 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2332 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2333 TRUE);
2334 /* Oddly enough, this fails */
2335 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2336 todo_wine
2337 ok(!ret, "Expected failure\n");
2338 CryptMsgClose(msg);
2339 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2340 NULL);
2341 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2342 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2343 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2344 /* Can't decrypt an indeterminate-type message */
2345 SetLastError(0xdeadbeef);
2346 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2347 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2348 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2349 CryptMsgClose(msg);
2351 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2352 NULL);
2353 /* Can't verify the hash of a signed message */
2354 SetLastError(0xdeadbeef);
2355 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2356 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2357 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2358 /* Can't decrypt a signed message */
2359 SetLastError(0xdeadbeef);
2360 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2361 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2362 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2363 /* Crash
2364 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2365 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2367 CryptMsgUpdate(msg, signedWithCertBareContent,
2368 sizeof(signedWithCertBareContent), TRUE);
2369 /* With an empty cert info, the signer can't be found in the message (and
2370 * the signature can't be verified.
2372 SetLastError(0xdeadbeef);
2373 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2374 ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2375 "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2376 /* The cert info is expected to have an issuer, serial number, and public
2377 * key info set.
2379 certInfo.SerialNumber.cbData = sizeof(serialNum);
2380 certInfo.SerialNumber.pbData = serialNum;
2381 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2382 certInfo.Issuer.pbData = encodedCommonName;
2383 SetLastError(0xdeadbeef);
2384 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2385 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2386 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2387 CryptMsgClose(msg);
2388 /* This cert has a public key, but it's not in a usable form */
2389 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2390 NULL);
2391 CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2392 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2393 /* Again, cert info needs to have a public key set */
2394 SetLastError(0xdeadbeef);
2395 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2396 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2397 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2398 /* The public key is supposed to be in encoded form.. */
2399 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2400 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2401 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2402 SetLastError(0xdeadbeef);
2403 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2404 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2405 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2406 /* but not as a X509_PUBLIC_KEY_INFO.. */
2407 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2408 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2409 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2410 SetLastError(0xdeadbeef);
2411 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2412 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2413 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2414 /* This decodes successfully, but it doesn't match any key in the message */
2415 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2416 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2417 SetLastError(0xdeadbeef);
2418 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2419 /* In Wine's rsaenh, this fails to decode because the key length is too
2420 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
2421 * now.
2423 todo_wine
2424 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2425 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2426 CryptMsgClose(msg);
2427 /* FIXME: need to test with a message with a valid signature and signer */
2430 static void test_msg_get_signer_count(void)
2432 LONG count;
2434 SetLastError(0xdeadbeef);
2435 count = CryptGetMessageSignerCount(0, NULL, 0);
2436 ok(count == -1, "Expected -1, got %d\n", count);
2437 ok(GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n",
2438 GetLastError());
2439 SetLastError(0xdeadbeef);
2440 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, NULL, 0);
2441 ok(count == -1, "Expected -1, got %d\n", count);
2442 ok(GetLastError() == CRYPT_E_ASN1_EOD,
2443 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2444 SetLastError(0xdeadbeef);
2445 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2446 dataEmptyBareContent, sizeof(dataEmptyBareContent));
2447 ok(count == -1, "Expected -1, got %d\n", count);
2448 ok(GetLastError() == CRYPT_E_ASN1_BADTAG,
2449 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2450 SetLastError(0xdeadbeef);
2451 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2452 dataEmptyContent, sizeof(dataEmptyContent));
2453 ok(count == -1, "Expected -1, got %d\n", count);
2454 ok(GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2455 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2456 SetLastError(0xdeadbeef);
2457 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2458 signedEmptyBareContent, sizeof(signedEmptyBareContent));
2459 ok(count == -1, "Expected -1, got %d\n", count);
2460 ok(GetLastError() == CRYPT_E_ASN1_BADTAG,
2461 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2462 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2463 signedEmptyContent, sizeof(signedEmptyContent));
2464 ok(count == 1, "Expected 1, got %d\n", count);
2467 START_TEST(msg)
2469 init_function_pointers();
2471 /* Basic parameter checking tests */
2472 test_msg_open_to_encode();
2473 test_msg_open_to_decode();
2474 test_msg_get_param();
2475 test_msg_close();
2476 test_msg_control();
2478 /* Message-type specific tests */
2479 test_data_msg();
2480 test_hash_msg();
2481 test_signed_msg();
2482 test_decode_msg();
2484 /* simplified message functions */
2485 test_msg_get_signer_count();