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