crypt32: Allow messages to be opened when compiled with CMSG_SIGNED_ENCODE_INFO_HAS_C...
[wine/gsoc_dplay.git] / dlls / crypt32 / tests / msg.c
blob0f691902079bb58ba1db268b1467920a3091c3d6
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 CryptReleaseContext(signer.hCryptProv, 0);
1110 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1111 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1114 static const BYTE privKey[] = {
1115 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1116 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1117 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1118 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1119 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1120 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1121 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1122 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1123 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1124 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1125 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1126 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1127 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1128 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1129 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1130 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1131 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1132 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1133 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1134 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1135 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1136 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1137 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1138 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1139 static BYTE pubKey[] = {
1140 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1141 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1142 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1143 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1144 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1146 static void test_signed_msg_update(void)
1148 HCRYPTMSG msg;
1149 BOOL ret;
1150 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1151 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1152 CERT_INFO certInfo = { 0 };
1153 HCRYPTKEY key;
1155 certInfo.SerialNumber.cbData = sizeof(serialNum);
1156 certInfo.SerialNumber.pbData = serialNum;
1157 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1158 certInfo.Issuer.pbData = encodedCommonName;
1159 signer.pCertInfo = &certInfo;
1160 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1161 signInfo.cSigners = 1;
1162 signInfo.rgSigners = &signer;
1164 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1165 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1166 if (!ret && GetLastError() == NTE_EXISTS) {
1167 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1168 PROV_RSA_FULL, 0);
1170 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1172 if (!ret) {
1173 skip("No context for tests\n");
1174 return;
1177 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1178 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1179 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1180 /* Detached CMSG_SIGNED allows non-final updates. */
1181 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1182 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1183 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1184 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1185 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1186 /* The final update requires a private key in the hCryptProv, in order to
1187 * generate the signature.
1189 SetLastError(0xdeadbeef);
1190 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1191 ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1192 GetLastError() == NTE_NO_KEY),
1193 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1194 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1195 0, 0, &key);
1196 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1197 /* The final update should be able to succeed now that a key exists, but
1198 * the previous (invalid) final update prevents it.
1200 SetLastError(0xdeadbeef);
1201 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1202 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1203 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1204 CryptMsgClose(msg);
1206 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1207 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1208 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1209 /* Detached CMSG_SIGNED allows non-final updates. */
1210 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1211 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1212 /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1213 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1214 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1215 /* Now that the private key exists, the final update can succeed (even
1216 * with no data.)
1218 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1219 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1220 /* But no updates are allowed after the final update. */
1221 SetLastError(0xdeadbeef);
1222 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1223 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1224 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1225 SetLastError(0xdeadbeef);
1226 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1227 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1228 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1229 CryptMsgClose(msg);
1231 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1232 NULL, NULL);
1233 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1234 /* Non-detached messages don't allow non-final updates.. */
1235 SetLastError(0xdeadbeef);
1236 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1237 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1238 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1239 /* but they do allow final ones. */
1240 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1241 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1242 CryptMsgClose(msg);
1243 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1244 NULL, NULL);
1245 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1246 /* They also allow final updates with no data. */
1247 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1248 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1249 CryptMsgClose(msg);
1251 CryptDestroyKey(key);
1252 CryptReleaseContext(signer.hCryptProv, 0);
1253 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1254 CRYPT_DELETEKEYSET);
1257 static const BYTE signedEmptyBareContent[] = {
1258 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1259 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1260 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1261 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1262 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1263 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1264 static const BYTE signedEmptyContent[] = {
1265 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1266 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1267 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1268 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1269 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1270 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1271 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1272 static const BYTE detachedSignedBareContent[] = {
1273 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1274 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1275 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1276 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1277 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1278 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1279 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1280 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1281 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1282 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1283 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1284 static const BYTE detachedSignedContent[] = {
1285 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1286 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1287 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1288 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1289 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1290 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1291 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1292 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1293 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1294 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1295 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1296 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1297 static const BYTE signedBareContent[] = {
1298 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1299 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1300 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1301 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1302 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1303 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1304 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1305 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1306 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1307 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1308 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1309 static const BYTE signedContent[] = {
1310 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1311 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1312 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1313 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1314 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1315 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1316 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1317 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1318 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1319 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1320 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1321 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1322 0x0d };
1323 static const BYTE signedHash[] = {
1324 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1325 0x2f };
1326 static const BYTE signedEncodedSigner[] = {
1327 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1328 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1329 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1330 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1331 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1332 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1333 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1334 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1335 static const BYTE signedWithAuthAttrsBareContent[] = {
1336 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1337 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1338 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1339 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1340 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1341 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1342 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1343 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1344 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1345 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1346 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1347 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1348 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1349 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1350 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1351 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1352 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1353 0xff,0xc6,0x33,0x63,0x34 };
1354 static BYTE cert[] = {
1355 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1356 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1357 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1358 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1359 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1360 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1361 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1362 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1363 0xff,0x02,0x01,0x01 };
1364 static BYTE v1CertWithPubKey[] = {
1365 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1366 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1367 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1368 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1369 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1370 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1371 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1372 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1373 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1374 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1375 0x01,0x01 };
1376 static const BYTE signedWithCertEmptyBareContent[] = {
1377 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1378 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1379 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1380 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1381 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1382 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1383 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1384 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1385 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1386 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1387 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1388 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1389 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1390 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1391 static const BYTE signedWithCertBareContent[] = {
1392 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1393 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1394 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1395 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1396 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1397 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1398 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1399 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1400 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1401 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1402 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1403 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1404 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1405 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1406 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1407 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1408 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1409 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1410 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1411 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1412 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1413 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1414 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1415 0x30,0x30,0x30,0x30,0x5a };
1416 static const BYTE signedWithCrlEmptyBareContent[] = {
1417 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1418 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1419 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1420 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1421 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1422 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1423 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1424 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1425 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1426 static const BYTE signedWithCrlBareContent[] = {
1427 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1428 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1429 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1430 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1431 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1432 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1433 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1434 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1435 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1436 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1437 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1438 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1439 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1440 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1441 0xa8,0x0d };
1442 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1443 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1444 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1445 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1446 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1447 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1448 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1449 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1450 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1451 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1452 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1453 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1454 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1455 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1456 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1457 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1458 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1459 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1460 0x04,0x00 };
1461 static const BYTE signedWithCertAndCrlBareContent[] = {
1462 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1463 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1464 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1465 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1466 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1467 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1468 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1469 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1470 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1471 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1472 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1473 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1474 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1475 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1476 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1477 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1478 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1479 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1480 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1481 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1482 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1483 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1484 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1485 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1486 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1487 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1488 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1489 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1490 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1491 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1492 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1493 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1494 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1495 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1496 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1497 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1498 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1499 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1500 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1501 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1502 static BYTE v1CertWithValidPubKey[] = {
1503 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1504 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1505 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1506 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1507 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1508 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1509 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1510 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1511 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1512 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1513 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1514 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1515 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1516 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1517 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1518 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1519 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1520 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1521 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1522 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1523 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1524 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1525 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1526 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1527 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1528 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1529 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1530 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1531 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1532 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1533 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1534 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1535 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1536 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1537 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1538 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1539 0x00 };
1540 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1541 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1542 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1543 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1544 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1545 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1546 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1547 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1548 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1549 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1550 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1551 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1552 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1553 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1554 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1555 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1556 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1557 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1558 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1559 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1560 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1561 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1562 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1563 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1564 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1565 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1566 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1567 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1569 static void test_signed_msg_encoding(void)
1571 HCRYPTMSG msg;
1572 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1573 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1574 CERT_INFO certInfo = { 0 };
1575 CERT_BLOB encodedCert = { sizeof(cert), cert };
1576 CRL_BLOB encodedCrl = { sizeof(crl), crl };
1577 char oid_common_name[] = szOID_COMMON_NAME;
1578 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1579 encodedCommonName };
1580 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1581 BOOL ret;
1582 HCRYPTKEY key;
1583 DWORD size;
1585 certInfo.SerialNumber.cbData = sizeof(serialNum);
1586 certInfo.SerialNumber.pbData = serialNum;
1587 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1588 certInfo.Issuer.pbData = encodedCommonName;
1589 signer.pCertInfo = &certInfo;
1590 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1591 signInfo.cSigners = 1;
1592 signInfo.rgSigners = &signer;
1594 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1595 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1596 if (!ret && GetLastError() == NTE_EXISTS) {
1597 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1598 PROV_RSA_FULL, 0);
1600 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1602 if (!ret) {
1603 skip("No context for tests\n");
1604 return;
1607 ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1608 0, 0, &key);
1609 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1611 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1612 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1613 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1615 check_param("detached signed empty bare content", msg,
1616 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1617 sizeof(signedEmptyBareContent));
1618 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1619 signedEmptyContent, sizeof(signedEmptyContent));
1620 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1621 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1622 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1623 signedHash, sizeof(signedHash));
1624 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1625 detachedSignedBareContent, sizeof(detachedSignedBareContent));
1626 check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1627 detachedSignedContent, sizeof(detachedSignedContent));
1628 SetLastError(0xdeadbeef);
1629 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1630 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1631 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1632 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1633 signedEncodedSigner, sizeof(signedEncodedSigner));
1635 CryptMsgClose(msg);
1637 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1638 NULL, NULL);
1639 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1641 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1642 signedEmptyBareContent, sizeof(signedEmptyBareContent));
1643 check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1644 signedEmptyContent, sizeof(signedEmptyContent));
1645 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1646 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1647 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1648 signedBareContent, sizeof(signedBareContent));
1649 check_param("signed content", msg, CMSG_CONTENT_PARAM,
1650 signedContent, sizeof(signedContent));
1652 CryptMsgClose(msg);
1654 signer.cAuthAttr = 1;
1655 signer.rgAuthAttr = &attr;
1656 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1657 NULL, NULL);
1658 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1660 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1661 check_param("signed with auth attrs bare content", msg,
1662 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1663 sizeof(signedWithAuthAttrsBareContent));
1665 CryptMsgClose(msg);
1667 signer.cAuthAttr = 0;
1668 signInfo.rgCertEncoded = &encodedCert;
1669 signInfo.cCertEncoded = 1;
1670 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1671 NULL, NULL);
1672 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1674 check_param("signed with cert empty bare content", msg,
1675 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1676 sizeof(signedWithCertEmptyBareContent));
1677 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1678 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1679 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1680 signedWithCertBareContent, sizeof(signedWithCertBareContent));
1682 CryptMsgClose(msg);
1684 signInfo.cCertEncoded = 0;
1685 signInfo.rgCrlEncoded = &encodedCrl;
1686 signInfo.cCrlEncoded = 1;
1687 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1688 NULL, NULL);
1689 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1691 check_param("signed with crl empty bare content", msg,
1692 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1693 sizeof(signedWithCrlEmptyBareContent));
1694 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1695 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1696 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1697 signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1699 CryptMsgClose(msg);
1701 signInfo.cCertEncoded = 1;
1702 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1703 NULL, NULL);
1704 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1706 check_param("signed with cert and crl empty bare content", msg,
1707 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1708 sizeof(signedWithCertAndCrlEmptyBareContent));
1709 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1710 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1711 check_param("signed with cert and crl bare content", msg,
1712 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1713 sizeof(signedWithCertAndCrlBareContent));
1715 CryptMsgClose(msg);
1717 /* Test with a cert with a (bogus) public key */
1718 signInfo.cCrlEncoded = 0;
1719 encodedCert.cbData = sizeof(v1CertWithPubKey);
1720 encodedCert.pbData = v1CertWithPubKey;
1721 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1722 NULL, NULL);
1723 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1724 check_param("signedWithCertWithPubKeyBareContent", msg,
1725 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1726 sizeof(signedWithCertWithPubKeyBareContent));
1727 CryptMsgClose(msg);
1729 encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1730 encodedCert.pbData = v1CertWithValidPubKey;
1731 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1732 NULL, NULL);
1733 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1734 check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1735 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1736 sizeof(signedWithCertWithValidPubKeyEmptyContent));
1737 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1738 check_param("signedWithCertWithValidPubKeyContent", msg,
1739 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1740 sizeof(signedWithCertWithValidPubKeyContent));
1741 CryptMsgClose(msg);
1743 CryptDestroyKey(key);
1744 CryptReleaseContext(signer.hCryptProv, 0);
1745 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1746 CRYPT_DELETEKEYSET);
1749 static void test_signed_msg_get_param(void)
1751 BOOL ret;
1752 HCRYPTMSG msg;
1753 DWORD size, value = 0;
1754 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1755 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1756 CERT_INFO certInfo = { 0 };
1758 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1759 NULL, NULL);
1760 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1762 /* Content and bare content are always gettable */
1763 size = 0;
1764 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1765 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1766 size = 0;
1767 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1768 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1769 /* For "signed" messages, so is the version. */
1770 size = 0;
1771 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1772 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1773 size = sizeof(value);
1774 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1775 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1776 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1777 /* But for this message, with no signers, the hash and signer aren't
1778 * available.
1780 size = 0;
1781 SetLastError(0xdeadbeef);
1782 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1783 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1784 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1785 SetLastError(0xdeadbeef);
1786 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1787 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1788 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1789 /* As usual, the type isn't available. */
1790 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1791 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1792 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1794 CryptMsgClose(msg);
1796 certInfo.SerialNumber.cbData = sizeof(serialNum);
1797 certInfo.SerialNumber.pbData = serialNum;
1798 certInfo.Issuer.cbData = sizeof(encodedCommonName);
1799 certInfo.Issuer.pbData = encodedCommonName;
1800 signer.pCertInfo = &certInfo;
1801 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1802 signInfo.cSigners = 1;
1803 signInfo.rgSigners = &signer;
1805 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1806 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1807 if (!ret && GetLastError() == NTE_EXISTS) {
1808 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1809 PROV_RSA_FULL, 0);
1811 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1813 if (!ret) {
1814 skip("No context for tests\n");
1815 return;
1818 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1819 NULL, NULL);
1820 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1822 /* This message, with one signer, has the hash and signer for index 0
1823 * available, but not for other indexes.
1825 size = 0;
1826 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1827 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1828 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1829 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1830 size = 0;
1831 SetLastError(0xdeadbeef);
1832 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1833 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1834 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1835 SetLastError(0xdeadbeef);
1836 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1837 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1838 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1839 /* As usual, the type isn't available. */
1840 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1841 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1842 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1844 CryptMsgClose(msg);
1846 CryptReleaseContext(signer.hCryptProv, 0);
1847 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1848 PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1851 static void test_signed_msg(void)
1853 test_signed_msg_open();
1854 test_signed_msg_update();
1855 test_signed_msg_encoding();
1856 test_signed_msg_get_param();
1859 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1860 static const struct update_accum a4 = { 1, &b4 };
1862 static const BYTE bogusOIDContent[] = {
1863 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1864 0x04,0x00 };
1865 static const BYTE bogusHashContent[] = {
1866 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1867 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1868 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1869 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1870 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1872 static void test_decode_msg_update(void)
1874 HCRYPTMSG msg;
1875 BOOL ret;
1876 CMSG_STREAM_INFO streamInfo = { 0 };
1877 DWORD i;
1878 struct update_accum accum = { 0, NULL };
1880 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1881 /* Update with a full message in a final update */
1882 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1883 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1884 /* Can't update after a final update */
1885 SetLastError(0xdeadbeef);
1886 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1887 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1888 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1889 CryptMsgClose(msg);
1891 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1892 /* Can't send a non-final update without streaming */
1893 SetLastError(0xdeadbeef);
1894 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1895 FALSE);
1896 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1897 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1898 /* A subsequent final update succeeds */
1899 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1900 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1901 CryptMsgClose(msg);
1903 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1904 /* Updating a message that has a NULL stream callback fails */
1905 SetLastError(0xdeadbeef);
1906 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1907 FALSE);
1908 todo_wine
1909 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1910 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1911 /* Changing the callback pointer after the fact yields the same error (so
1912 * the message must copy the stream info, not just store a pointer to it)
1914 streamInfo.pfnStreamOutput = nop_stream_output;
1915 SetLastError(0xdeadbeef);
1916 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1917 FALSE);
1918 todo_wine
1919 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1920 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1921 CryptMsgClose(msg);
1923 /* Empty non-final updates are allowed when streaming.. */
1924 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1925 ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1926 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1927 /* but final updates aren't when not enough data has been received. */
1928 SetLastError(0xdeadbeef);
1929 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1930 todo_wine
1931 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1932 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1933 CryptMsgClose(msg);
1935 /* Updating the message byte by byte is legal */
1936 streamInfo.pfnStreamOutput = accumulating_stream_output;
1937 streamInfo.pvArg = &accum;
1938 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1939 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1940 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1941 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1942 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1943 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1944 CryptMsgClose(msg);
1945 todo_wine
1946 check_updates("byte-by-byte empty content", &a4, &accum);
1947 free_updates(&accum);
1949 /* Decoding bogus content fails in non-streaming mode.. */
1950 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1951 SetLastError(0xdeadbeef);
1952 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1953 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1954 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1955 CryptMsgClose(msg);
1956 /* and as the final update in streaming mode.. */
1957 streamInfo.pfnStreamOutput = nop_stream_output;
1958 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1959 SetLastError(0xdeadbeef);
1960 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1961 todo_wine
1962 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1963 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1964 CryptMsgClose(msg);
1965 /* and even as a non-final update in streaming mode. */
1966 streamInfo.pfnStreamOutput = nop_stream_output;
1967 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1968 SetLastError(0xdeadbeef);
1969 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1970 todo_wine
1971 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1972 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1973 CryptMsgClose(msg);
1975 /* An empty message can be opened with undetermined type.. */
1976 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1977 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1978 TRUE);
1979 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1980 CryptMsgClose(msg);
1981 /* but decoding it as an explicitly typed message fails. */
1982 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1983 NULL);
1984 SetLastError(0xdeadbeef);
1985 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1986 TRUE);
1987 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1988 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1989 CryptMsgClose(msg);
1990 /* On the other hand, decoding the bare content of an empty message fails
1991 * with unspecified type..
1993 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1994 SetLastError(0xdeadbeef);
1995 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1996 sizeof(dataEmptyBareContent), TRUE);
1997 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1998 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1999 CryptMsgClose(msg);
2000 /* but succeeds with explicit type. */
2001 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2002 NULL);
2003 ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2004 sizeof(dataEmptyBareContent), TRUE);
2005 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2006 CryptMsgClose(msg);
2008 /* Decoding valid content with an unsupported OID fails */
2009 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2010 SetLastError(0xdeadbeef);
2011 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2012 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2013 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2014 CryptMsgClose(msg);
2016 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2017 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2018 SetLastError(0xdeadbeef);
2019 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2020 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2021 CryptMsgClose(msg);
2022 /* while with specified type it fails. */
2023 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2024 NULL);
2025 SetLastError(0xdeadbeef);
2026 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2027 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2028 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2029 CryptMsgClose(msg);
2030 /* On the other hand, decoding the bare content of an empty hash message
2031 * fails with unspecified type..
2033 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2034 SetLastError(0xdeadbeef);
2035 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2036 sizeof(hashEmptyBareContent), TRUE);
2037 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2038 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2039 CryptMsgClose(msg);
2040 /* but succeeds with explicit type. */
2041 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2042 NULL);
2043 ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2044 sizeof(hashEmptyBareContent), TRUE);
2045 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2046 CryptMsgClose(msg);
2048 /* And again, opening a (non-empty) hash message with unspecified type
2049 * succeeds..
2051 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2052 SetLastError(0xdeadbeef);
2053 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2054 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2055 CryptMsgClose(msg);
2056 /* while with specified type it fails.. */
2057 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2058 NULL);
2059 SetLastError(0xdeadbeef);
2060 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2061 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2062 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2063 CryptMsgClose(msg);
2064 /* and decoding the bare content of a non-empty hash message fails with
2065 * unspecified type..
2067 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2068 SetLastError(0xdeadbeef);
2069 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2070 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2071 "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2072 CryptMsgClose(msg);
2073 /* but succeeds with explicit type. */
2074 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2075 NULL);
2076 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2077 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2078 CryptMsgClose(msg);
2080 /* Opening a (non-empty) hash message with unspecified type and a bogus
2081 * hash value succeeds..
2083 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2084 SetLastError(0xdeadbeef);
2085 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2086 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2087 CryptMsgClose(msg);
2089 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2090 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2091 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2092 CryptMsgClose(msg);
2093 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2094 SetLastError(0xdeadbeef);
2095 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2096 sizeof(signedWithCertAndCrlBareContent), TRUE);
2097 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2098 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2099 CryptMsgClose(msg);
2100 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2101 NULL);
2102 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2103 sizeof(signedWithCertAndCrlBareContent), TRUE);
2104 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2105 CryptMsgClose(msg);
2107 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2108 NULL, NULL);
2109 /* The first update succeeds.. */
2110 ret = CryptMsgUpdate(msg, detachedSignedContent,
2111 sizeof(detachedSignedContent), TRUE);
2112 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2113 /* as does a second (probably to update the detached portion).. */
2114 ret = CryptMsgUpdate(msg, detachedSignedContent,
2115 sizeof(detachedSignedContent), TRUE);
2116 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2117 /* while a third fails. */
2118 ret = CryptMsgUpdate(msg, detachedSignedContent,
2119 sizeof(detachedSignedContent), TRUE);
2120 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2121 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2122 CryptMsgClose(msg);
2125 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2126 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2128 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2129 const CMSG_SIGNER_INFO *expected)
2131 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2132 expected->dwVersion, got->dwVersion);
2133 ok(got->Issuer.cbData == expected->Issuer.cbData,
2134 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2135 got->Issuer.cbData);
2136 ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2137 "Unexpected issuer\n");
2138 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2139 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2140 got->SerialNumber.cbData);
2141 ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2142 got->SerialNumber.cbData), "Unexpected serial number\n");
2143 /* FIXME: check more things */
2146 static const BYTE signedWithCertAndCrlComputedHash[] = {
2147 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2148 0x2f };
2150 static void test_decode_msg_get_param(void)
2152 HCRYPTMSG msg;
2153 BOOL ret;
2154 DWORD size = 0, value;
2155 LPBYTE buf;
2157 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2158 SetLastError(0xdeadbeef);
2159 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2160 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2161 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2162 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2163 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2164 sizeof(msgData));
2165 CryptMsgClose(msg);
2167 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2168 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2169 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2170 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2171 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2172 emptyHashParam, sizeof(emptyHashParam));
2173 CryptMsgClose(msg);
2174 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2175 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2176 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2177 sizeof(msgData));
2178 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2179 sizeof(hashParam));
2180 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2181 hashParam, sizeof(hashParam));
2182 /* Curiously, getting the hash of index 1 succeeds, even though there's
2183 * only one hash.
2185 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2186 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2187 buf = CryptMemAlloc(size);
2188 if (buf)
2190 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2191 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2192 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2193 CryptMemFree(buf);
2195 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2196 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2197 value = CMSG_HASHED_DATA_V0;
2198 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2199 sizeof(value));
2200 CryptMsgClose(msg);
2202 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2203 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2204 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2205 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2206 sizeof(msgData));
2207 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2208 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2209 size = sizeof(value);
2210 value = 2112;
2211 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2212 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2213 ok(value == 1, "Expected 1 signer, got %d\n", value);
2214 size = 0;
2215 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2216 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2217 if (ret)
2218 buf = CryptMemAlloc(size);
2219 else
2220 buf = NULL;
2221 if (buf)
2223 CMSG_SIGNER_INFO signer = { 0 };
2225 signer.dwVersion = 1;
2226 signer.Issuer.cbData = sizeof(encodedCommonName);
2227 signer.Issuer.pbData = encodedCommonName;
2228 signer.SerialNumber.cbData = sizeof(serialNum);
2229 signer.SerialNumber.pbData = serialNum;
2230 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2231 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2232 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2233 CryptMemFree(buf);
2235 /* index is ignored when getting signer count */
2236 size = sizeof(value);
2237 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2238 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2239 ok(value == 1, "Expected 1 signer, got %d\n", value);
2240 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2241 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2242 ok(value == 0, "Expected 0 certs, got %d\n", value);
2243 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2244 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2245 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2246 CryptMsgClose(msg);
2247 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2248 NULL);
2249 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2250 sizeof(signedWithCertAndCrlBareContent), TRUE);
2251 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2252 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2253 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2254 ok(value == 1, "Expected 1 cert, got %d\n", value);
2255 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2256 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2257 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2258 ok(value == 1, "Expected 1 CRL, got %d\n", value);
2259 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2260 check_param("signed with cert and CRL computed hash", msg,
2261 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2262 sizeof(signedWithCertAndCrlComputedHash));
2263 CryptMsgClose(msg);
2266 static void test_decode_msg(void)
2268 test_decode_msg_update();
2269 test_decode_msg_get_param();
2272 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2273 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2274 static BYTE encodedPubKey[] = {
2275 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2276 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2277 0x0d,0x0e,0x0f };
2278 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2279 static BYTE mod_encoded[] = {
2280 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2281 0x01,0x00,0x01 };
2283 static void test_msg_control(void)
2285 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2286 BOOL ret;
2287 HCRYPTMSG msg;
2288 DWORD i;
2289 CERT_INFO certInfo = { 0 };
2290 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2291 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2292 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2294 /* Crashes
2295 ret = CryptMsgControl(NULL, 0, 0, NULL);
2298 /* Data encode messages don't allow any sort of control.. */
2299 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2300 NULL);
2301 /* either with no prior update.. */
2302 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2304 SetLastError(0xdeadbeef);
2305 ret = CryptMsgControl(msg, 0, i, NULL);
2306 ok(!ret && GetLastError() == E_INVALIDARG,
2307 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2309 /* or after an update. */
2310 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2312 SetLastError(0xdeadbeef);
2313 ret = CryptMsgControl(msg, 0, i, NULL);
2314 ok(!ret && GetLastError() == E_INVALIDARG,
2315 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2317 CryptMsgClose(msg);
2319 /* Hash encode messages don't allow any sort of control.. */
2320 hashInfo.cbSize = sizeof(hashInfo);
2321 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2322 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2323 NULL, NULL);
2324 /* either with no prior update.. */
2325 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2327 SetLastError(0xdeadbeef);
2328 ret = CryptMsgControl(msg, 0, i, NULL);
2329 ok(!ret && GetLastError() == E_INVALIDARG,
2330 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2332 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2333 /* or after an update. */
2334 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2336 SetLastError(0xdeadbeef);
2337 ret = CryptMsgControl(msg, 0, i, NULL);
2338 ok(!ret && GetLastError() == E_INVALIDARG,
2339 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2341 CryptMsgClose(msg);
2343 /* Signed encode messages likewise don't allow any sort of control.. */
2344 signInfo.cbSize = sizeof(signInfo);
2345 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2346 NULL, NULL);
2347 /* either before an update.. */
2348 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2350 SetLastError(0xdeadbeef);
2351 ret = CryptMsgControl(msg, 0, i, NULL);
2352 ok(!ret && GetLastError() == E_INVALIDARG,
2353 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2355 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2356 /* or after an update. */
2357 for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2359 SetLastError(0xdeadbeef);
2360 ret = CryptMsgControl(msg, 0, i, NULL);
2361 ok(!ret && GetLastError() == E_INVALIDARG,
2362 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2364 CryptMsgClose(msg);
2366 /* Decode messages behave a bit differently. */
2367 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2368 /* Bad control type */
2369 SetLastError(0xdeadbeef);
2370 ret = CryptMsgControl(msg, 0, 0, NULL);
2371 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2372 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2373 SetLastError(0xdeadbeef);
2374 ret = CryptMsgControl(msg, 1, 0, NULL);
2375 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2376 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2377 /* Can't verify the hash of an indeterminate-type message */
2378 SetLastError(0xdeadbeef);
2379 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2380 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2381 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2382 /* Crashes
2383 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2385 /* Can't decrypt an indeterminate-type message */
2386 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2387 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2388 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2389 CryptMsgClose(msg);
2391 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2392 NULL);
2393 /* Can't verify the hash of an empty message */
2394 SetLastError(0xdeadbeef);
2395 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2396 todo_wine
2397 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2398 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2399 /* Crashes
2400 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2402 /* Can't verify the signature of a hash message */
2403 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2404 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2405 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2406 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2407 TRUE);
2408 /* Oddly enough, this fails */
2409 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2410 todo_wine
2411 ok(!ret, "Expected failure\n");
2412 CryptMsgClose(msg);
2413 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2414 NULL);
2415 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2416 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2417 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2418 /* Can't decrypt an indeterminate-type message */
2419 SetLastError(0xdeadbeef);
2420 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2421 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2422 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2423 CryptMsgClose(msg);
2425 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2426 NULL);
2427 /* Can't verify the hash of a signed message */
2428 SetLastError(0xdeadbeef);
2429 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2430 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2431 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2432 /* Can't decrypt a signed message */
2433 SetLastError(0xdeadbeef);
2434 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2435 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2436 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2437 /* Crash
2438 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2439 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2441 CryptMsgUpdate(msg, signedWithCertBareContent,
2442 sizeof(signedWithCertBareContent), TRUE);
2443 /* With an empty cert info, the signer can't be found in the message (and
2444 * the signature can't be verified.
2446 SetLastError(0xdeadbeef);
2447 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2448 ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2449 "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2450 /* The cert info is expected to have an issuer, serial number, and public
2451 * key info set.
2453 certInfo.SerialNumber.cbData = sizeof(serialNum);
2454 certInfo.SerialNumber.pbData = serialNum;
2455 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2456 certInfo.Issuer.pbData = encodedCommonName;
2457 SetLastError(0xdeadbeef);
2458 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2459 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2460 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2461 CryptMsgClose(msg);
2462 /* This cert has a public key, but it's not in a usable form */
2463 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2464 NULL);
2465 CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2466 sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2467 /* Again, cert info needs to have a public key set */
2468 SetLastError(0xdeadbeef);
2469 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2470 ok(!ret &&
2471 (GetLastError() == CRYPT_E_ASN1_EOD ||
2472 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2473 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2474 /* The public key is supposed to be in encoded form.. */
2475 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2476 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2477 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2478 SetLastError(0xdeadbeef);
2479 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2480 ok(!ret &&
2481 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2482 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2483 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2484 /* but not as a X509_PUBLIC_KEY_INFO.. */
2485 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2486 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2487 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2488 SetLastError(0xdeadbeef);
2489 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2490 ok(!ret &&
2491 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2492 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2493 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2494 /* This decodes successfully, but it doesn't match any key in the message */
2495 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2496 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2497 SetLastError(0xdeadbeef);
2498 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2499 /* In Wine's rsaenh, this fails to decode because the key length is too
2500 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
2501 * now.
2503 todo_wine
2504 ok(!ret &&
2505 (GetLastError() == NTE_BAD_SIGNATURE ||
2506 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2507 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2508 CryptMsgClose(msg);
2509 /* A message with no data doesn't have a valid signature */
2510 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2511 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2512 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2513 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2514 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2515 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2516 SetLastError(0xdeadbeef);
2517 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2518 ok(!ret &&
2519 (GetLastError() == NTE_BAD_SIGNATURE ||
2520 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2521 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2522 CryptMsgClose(msg);
2523 /* Finally, this succeeds */
2524 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2525 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2526 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2527 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2528 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2529 CryptMsgClose(msg);
2532 /* win9x has much less parameter checks and will crash on many tests
2533 * this code is from test_signed_msg_update()
2535 static BOOL detect_nt(void)
2537 BOOL ret;
2538 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
2539 CERT_INFO certInfo = { 0 };
2542 certInfo.SerialNumber.cbData = sizeof(serialNum);
2543 certInfo.SerialNumber.pbData = serialNum;
2544 certInfo.Issuer.cbData = sizeof(encodedCommonName);
2545 certInfo.Issuer.pbData = encodedCommonName;
2546 signer.pCertInfo = &certInfo;
2547 signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2549 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2550 PROV_RSA_FULL, CRYPT_NEWKEYSET);
2551 if (!ret && GetLastError() == NTE_EXISTS) {
2552 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2553 PROV_RSA_FULL, 0);
2556 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
2558 /* cleanup */
2559 CryptReleaseContext(signer.hCryptProv, 0);
2560 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
2561 CRYPT_DELETEKEYSET);
2563 return TRUE;
2566 static void test_msg_get_and_verify_signer(void)
2568 BOOL ret;
2569 HCRYPTMSG msg;
2570 PCCERT_CONTEXT signer;
2571 DWORD signerIndex;
2572 HCERTSTORE store;
2574 /* Crash */
2575 if (0)
2577 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
2578 ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
2581 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2582 /* An empty message has no signer */
2583 SetLastError(0xdeadbeef);
2584 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2585 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2586 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2587 /* The signer is cleared on error */
2588 signer = (PCCERT_CONTEXT)0xdeadbeef;
2589 SetLastError(0xdeadbeef);
2590 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2591 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2592 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2593 ok(!signer, "expected signer to be NULL\n");
2594 /* The signer index is also cleared on error */
2595 signerIndex = 0xdeadbeef;
2596 SetLastError(0xdeadbeef);
2597 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2598 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2599 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2600 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
2601 /* An unsigned message (msgData isn't a signed message at all)
2602 * likewise has no signer.
2604 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2605 SetLastError(0xdeadbeef);
2606 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2607 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2608 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2609 CryptMsgClose(msg);
2611 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2612 /* A "signed" message created with no signer cert likewise has no signer */
2613 CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
2614 SetLastError(0xdeadbeef);
2615 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2616 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2617 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2618 CryptMsgClose(msg);
2620 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2621 /* A signed message succeeds, .. */
2622 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2623 sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2624 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2625 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2626 /* the signer index can be retrieved, .. */
2627 signerIndex = 0xdeadbeef;
2628 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2629 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2630 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
2631 /* as can the signer cert. */
2632 signer = (PCCERT_CONTEXT)0xdeadbeef;
2633 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2634 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2635 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
2636 "expected a valid signer\n");
2637 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
2638 CertFreeCertificateContext(signer);
2639 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
2641 signerIndex = 0xdeadbeef;
2642 SetLastError(0xdeadbeef);
2643 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
2644 NULL, &signerIndex);
2645 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
2646 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
2647 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
2648 * message signer not to be found.
2650 SetLastError(0xdeadbeef);
2651 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
2652 NULL, NULL);
2653 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2654 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2655 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
2656 * the message signer not to be found.
2658 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
2659 CERT_STORE_CREATE_NEW_FLAG, NULL);
2660 SetLastError(0xdeadbeef);
2661 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
2662 NULL, NULL);
2663 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2664 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2665 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
2666 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
2667 CERT_STORE_ADD_ALWAYS, NULL);
2668 ok(ret, "CertAddEncodedCertificateToStore failed: 0x%08x\n",
2669 GetLastError());
2670 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
2671 * the signer succeeds.
2673 SetLastError(0xdeadbeef);
2674 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
2675 NULL, NULL);
2676 ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2677 CertCloseStore(store, 0);
2678 CryptMsgClose(msg);
2681 START_TEST(msg)
2683 init_function_pointers();
2684 have_nt = detect_nt();
2686 /* Basic parameter checking tests */
2687 test_msg_open_to_encode();
2688 test_msg_open_to_decode();
2689 test_msg_get_param();
2690 test_msg_close();
2691 test_msg_control();
2693 /* Message-type specific tests */
2694 test_data_msg();
2695 test_hash_msg();
2696 test_signed_msg();
2697 test_decode_msg();
2699 test_msg_get_and_verify_signer();