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