crypt32: Implement CryptVerifyMessageSignature.
[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     todo_wine
663     check_updates("data message with indefinite length", &a3, &accum);
664     free_updates(&accum);
665 }
666
667 static void test_data_msg(void)
668 {
669     test_data_msg_open();
670     test_data_msg_update();
671     test_data_msg_get_param();
672     test_data_msg_encoding();
673 }
674
675 static void test_hash_msg_open(void)
676 {
677     HCRYPTMSG msg;
678     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
679     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
680
681     SetLastError(0xdeadbeef);
682     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
683      NULL, NULL);
684     ok(!msg && GetLastError() == E_INVALIDARG,
685      "Expected E_INVALIDARG, got %x\n", GetLastError());
686     hashInfo.cbSize = sizeof(hashInfo);
687     SetLastError(0xdeadbeef);
688     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
689      NULL, NULL);
690     ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
691      "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
692     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
693     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
694      NULL, NULL);
695     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
696     CryptMsgClose(msg);
697     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
698      CMSG_HASHED, &hashInfo, NULL, NULL);
699     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
700     CryptMsgClose(msg);
701     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
702      CMSG_HASHED, &hashInfo, NULL, &streamInfo);
703     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
704     CryptMsgClose(msg);
705 }
706
707 static void test_hash_msg_update(void)
708 {
709     HCRYPTMSG msg;
710     BOOL ret;
711     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
712      { oid_rsa_md5, { 0, NULL } }, NULL };
713     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
714
715     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
716      CMSG_HASHED, &hashInfo, NULL, NULL);
717     /* Detached hashed messages opened in non-streaming mode allow non-final
718      * updates..
719      */
720     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
721     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
722     /* including non-final updates with no data.. */
723     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
724     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
725     /* and final updates with no data. */
726     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
727     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
728     /* But no updates are allowed after the final update. */
729     SetLastError(0xdeadbeef);
730     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
731     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
732      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
733     SetLastError(0xdeadbeef);
734     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
735     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
736      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
737     CryptMsgClose(msg);
738     /* Non-detached messages, in contrast, don't allow non-final updates in
739      * non-streaming mode.
740      */
741     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
742      NULL, NULL);
743     SetLastError(0xdeadbeef);
744     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
745     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
746      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
747     /* Final updates (including empty ones) are allowed. */
748     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
749     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
750     CryptMsgClose(msg);
751     /* And, of course, streaming mode allows non-final updates */
752     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
753      NULL, &streamInfo);
754     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
755     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
756     CryptMsgClose(msg);
757     /* Setting pfnStreamOutput to NULL results in no error.  (In what appears
758      * to be a bug, it isn't actually used - see encoding tests.)
759      */
760     streamInfo.pfnStreamOutput = NULL;
761     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
762      NULL, &streamInfo);
763     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
764     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
765     CryptMsgClose(msg);
766 }
767
768 static const BYTE emptyHashParam[] = {
769 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
770 0x7e };
771
772 static void test_hash_msg_get_param(void)
773 {
774     HCRYPTMSG msg;
775     BOOL ret;
776     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
777      { oid_rsa_md5, { 0, NULL } }, NULL };
778     DWORD size, value;
779     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
780     BYTE buf[16];
781
782     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
783      NULL, NULL);
784     /* Content and bare content are always gettable for non-streamed messages */
785     size = 0;
786     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
787     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
788     size = 0;
789     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
790     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
791     /* For an encoded hash message, the hash data aren't available */
792     SetLastError(0xdeadbeef);
793     ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
794     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
795      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
796     /* The hash is also available. */
797     size = 0;
798     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
799     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
800     ok(size == sizeof(buf), "Unexpected size %d\n", size);
801     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
802     if (size == sizeof(buf))
803         ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
804     /* By getting the hash, further updates are not allowed */
805     SetLastError(0xdeadbeef);
806     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
807     ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
808      "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
809     /* Even after a final update, the hash data aren't available */
810     SetLastError(0xdeadbeef);
811     ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
812     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
813      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
814     /* The version is also available, and should be zero for this message. */
815     size = 0;
816     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
817     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
818     size = sizeof(value);
819     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
820     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
821     ok(value == 0, "Expected version 0, got %d\n", value);
822     /* As usual, the type isn't available. */
823     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
824     ok(!ret, "Expected failure\n");
825     CryptMsgClose(msg);
826
827     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
828      NULL, &streamInfo);
829     /* Streamed messages don't allow you to get the content or bare content. */
830     SetLastError(0xdeadbeef);
831     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
832     ok(!ret && GetLastError() == E_INVALIDARG,
833      "Expected E_INVALIDARG, got %x\n", GetLastError());
834     SetLastError(0xdeadbeef);
835     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
836     ok(!ret && GetLastError() == E_INVALIDARG,
837      "Expected E_INVALIDARG, got %x\n", GetLastError());
838     /* The hash is still available. */
839     size = 0;
840     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
841     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
842     ok(size == sizeof(buf), "Unexpected size %d\n", size);
843     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
844     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
845     if (size == sizeof(buf))
846         ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
847     /* After updating the hash, further updates aren't allowed on streamed
848      * messages either.
849      */
850     SetLastError(0xdeadbeef);
851     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
852     ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
853      "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
854     CryptMsgClose(msg);
855 }
856
857 static const BYTE hashEmptyBareContent[] = {
858 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
859 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
860 static const BYTE hashEmptyContent[] = {
861 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
862 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
863 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
864 static const BYTE hashBareContent[] = {
865 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
866 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
867 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
868 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
869 static const BYTE hashContent[] = {
870 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
871 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
872 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
873 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
874 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
875
876 static const BYTE detachedHashNonFinalBareContent[] = {
877 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
878 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
879 0x07,0x01,0x04,0x00 };
880 static const BYTE detachedHashNonFinalContent[] = {
881 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
882 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
883 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
884 0x07,0x01,0x04,0x00 };
885 static const BYTE detachedHashBareContent[] = {
886 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
887 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
888 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
889 0x9d,0x2a,0x8f,0x26,0x2f };
890 static const BYTE detachedHashContent[] = {
891 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
892 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
893 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
894 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
895 0x9d,0x2a,0x8f,0x26,0x2f };
896
897 static void test_hash_msg_encoding(void)
898 {
899     HCRYPTMSG msg;
900     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
901     BOOL ret;
902     struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
903     CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
904
905     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
906     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
907      NULL, NULL);
908     check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
909      hashEmptyBareContent, sizeof(hashEmptyBareContent));
910     check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
911      hashEmptyContent, sizeof(hashEmptyContent));
912     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
913     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
914     check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
915      hashBareContent, sizeof(hashBareContent));
916     check_param("hash content", msg, CMSG_CONTENT_PARAM,
917      hashContent, sizeof(hashContent));
918     CryptMsgClose(msg);
919     /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
920     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
921      CMSG_HASHED, &hashInfo, NULL, NULL);
922     check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
923      hashEmptyBareContent, sizeof(hashEmptyBareContent));
924     check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
925      hashEmptyContent, sizeof(hashEmptyContent));
926     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
927     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
928     check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
929      hashBareContent, sizeof(hashBareContent));
930     check_param("hash content", msg, CMSG_CONTENT_PARAM,
931      hashContent, sizeof(hashContent));
932     CryptMsgClose(msg);
933     /* Same test, but with CMSG_DETACHED_FLAG set */
934     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
935      CMSG_HASHED, &hashInfo, NULL, NULL);
936     check_param("detached hash empty bare content", msg,
937      CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
938      sizeof(hashEmptyBareContent));
939     check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
940      hashEmptyContent, sizeof(hashEmptyContent));
941     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
942     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
943     check_param("detached hash not final bare content", msg,
944      CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
945      sizeof(detachedHashNonFinalBareContent));
946     check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
947      detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
948     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
949     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
950     check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
951      detachedHashBareContent, sizeof(detachedHashBareContent));
952     check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
953      detachedHashContent, sizeof(detachedHashContent));
954     check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
955      detachedHashBareContent, sizeof(detachedHashBareContent));
956     check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
957      detachedHashContent, sizeof(detachedHashContent));
958     CryptMsgClose(msg);
959     /* In what appears to be a bug, streamed updates to hash messages don't
960      * call the output function.
961      */
962     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
963      NULL, &streamInfo);
964     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
965     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
966     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
967     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
968     CryptMsgClose(msg);
969     check_updates("empty hash message", &empty_accum, &accum);
970     free_updates(&accum);
971
972     streamInfo.cbContent = sizeof(msgData);
973     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
974      NULL, &streamInfo);
975     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
976     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
977     CryptMsgClose(msg);
978     check_updates("hash message", &empty_accum, &accum);
979     free_updates(&accum);
980
981     streamInfo.cbContent = sizeof(msgData);
982     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
983      CMSG_HASHED, &hashInfo, NULL, &streamInfo);
984     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
985     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
986     CryptMsgClose(msg);
987     check_updates("detached hash message", &empty_accum, &accum);
988     free_updates(&accum);
989 }
990
991 static void test_hash_msg(void)
992 {
993     test_hash_msg_open();
994     test_hash_msg_update();
995     test_hash_msg_get_param();
996     test_hash_msg_encoding();
997 }
998
999 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1000  'm','p',0 };
1001 static BYTE serialNum[] = { 1 };
1002 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1003  0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1004
1005 static void test_signed_msg_open(void)
1006 {
1007     HCRYPTMSG msg;
1008     BOOL ret;
1009     CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1010     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1011     CERT_INFO certInfo = { 0 };
1012
1013     SetLastError(0xdeadbeef);
1014     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1015      NULL, NULL);
1016     ok(!msg && GetLastError() == E_INVALIDARG,
1017      "Expected E_INVALIDARG, got %x\n", GetLastError());
1018     signInfo.cbSize = sizeof(signInfo);
1019     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1020      NULL, NULL);
1021     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1022     CryptMsgClose(msg);
1023
1024     signInfo.cSigners = 1;
1025     signInfo.rgSigners = &signer;
1026     /* With signer.pCertInfo unset, attempting to open this message this
1027      * crashes.
1028      */
1029     signer.pCertInfo = &certInfo;
1030     /* The cert info must contain a serial number and an issuer. */
1031     SetLastError(0xdeadbeef);
1032     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1033      NULL, NULL);
1034     ok(!msg && GetLastError() == E_INVALIDARG,
1035      "Expected E_INVALIDARG, got %x\n", GetLastError());
1036     certInfo.SerialNumber.cbData = sizeof(serialNum);
1037     certInfo.SerialNumber.pbData = serialNum;
1038     SetLastError(0xdeadbeef);
1039     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1040      NULL, NULL);
1041     ok(!msg && GetLastError() == E_INVALIDARG,
1042      "Expected E_INVALIDARG, got %x\n", GetLastError());
1043     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1044     certInfo.Issuer.pbData = encodedCommonName;
1045     SetLastError(0xdeadbeef);
1046     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1047      NULL, NULL);
1048     ok(!msg && GetLastError() == E_INVALIDARG,
1049      "Expected E_INVALIDARG, got %x\n", GetLastError());
1050
1051     /* The signer's hCryptProv must be set to something.  Whether it's usable
1052      * or not will be checked after the hash algorithm is checked (see next
1053      * test.)
1054      */
1055     signer.hCryptProv = 1;
1056     SetLastError(0xdeadbeef);
1057     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1058      NULL, NULL);
1059     ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1060      "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1061     /* The signer's hash algorithm must also be set. */
1062     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1063     SetLastError(0xdeadbeef);
1064     /* Crashes in advapi32 in wine, don't do it */
1065     if (0) {
1066         msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1067          &signInfo, NULL, NULL);
1068         ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1069          "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1070     }
1071     /* The signer's hCryptProv must also be valid. */
1072     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1073      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1074     if (!ret && GetLastError() == NTE_EXISTS)
1075         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1076          PROV_RSA_FULL, 0);
1077     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1078     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1079      NULL, NULL);
1080     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1081     CryptMsgClose(msg);
1082
1083     CryptReleaseContext(signer.hCryptProv, 0);
1084     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1085      PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1086 }
1087
1088 static const BYTE privKey[] = {
1089  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1090  0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1091  0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1092  0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1093  0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1094  0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1095  0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1096  0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1097  0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1098  0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1099  0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1100  0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1101  0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1102  0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1103  0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1104  0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1105  0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1106  0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1107  0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1108  0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1109  0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1110  0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1111  0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1112  0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1113 static BYTE pubKey[] = {
1114 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1115 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1116 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1117 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1118 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1119
1120 static void test_signed_msg_update(void)
1121 {
1122     HCRYPTMSG msg;
1123     BOOL ret;
1124     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1125     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1126     CERT_INFO certInfo = { 0 };
1127     HCRYPTKEY key;
1128
1129     certInfo.SerialNumber.cbData = sizeof(serialNum);
1130     certInfo.SerialNumber.pbData = serialNum;
1131     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1132     certInfo.Issuer.pbData = encodedCommonName;
1133     signer.pCertInfo = &certInfo;
1134     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1135     signInfo.cSigners = 1;
1136     signInfo.rgSigners = &signer;
1137     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1138      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1139     if (!ret && GetLastError() == NTE_EXISTS)
1140         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1141          PROV_RSA_FULL, 0);
1142     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1143     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1144      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1145     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1146     /* Detached CMSG_SIGNED allows non-final updates. */
1147     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1148     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1149     /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1150     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1151     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1152     /* The final update requires a private key in the hCryptProv, in order to
1153      * generate the signature.
1154      */
1155     SetLastError(0xdeadbeef);
1156     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1157     ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1158      GetLastError() == NTE_NO_KEY),
1159      "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1160     ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1161      0, 0, &key);
1162     ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1163     /* The final update should be able to succeed now that a key exists, but
1164      * the previous (invalid) final update prevents it.
1165      */
1166     SetLastError(0xdeadbeef);
1167     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1168     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1169      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1170     CryptMsgClose(msg);
1171
1172     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1173      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1174     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1175     /* Detached CMSG_SIGNED allows non-final updates. */
1176     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1177     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1178     /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1179     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1180     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1181     /* Now that the private key exists, the final update can succeed (even
1182      * with no data.)
1183      */
1184     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1185     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1186     /* But no updates are allowed after the final update. */
1187     SetLastError(0xdeadbeef);
1188     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1189     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1190      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1191     SetLastError(0xdeadbeef);
1192     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1193     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1194      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1195     CryptMsgClose(msg);
1196
1197     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1198      NULL, NULL);
1199     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1200     /* Non-detached messages don't allow non-final updates.. */
1201     SetLastError(0xdeadbeef);
1202     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1203     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1204      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1205     /* but they do allow final ones. */
1206     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1207     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1208     CryptMsgClose(msg);
1209     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1210      NULL, NULL);
1211     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1212     /* They also allow final updates with no data. */
1213     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1214     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1215     CryptMsgClose(msg);
1216
1217     CryptDestroyKey(key);
1218     CryptReleaseContext(signer.hCryptProv, 0);
1219     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1220      CRYPT_DELETEKEYSET);
1221 }
1222
1223 static const BYTE signedEmptyBareContent[] = {
1224 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1225 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1226 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1227 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1228 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1229 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1230 static const BYTE signedEmptyContent[] = {
1231 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1232 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1233 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1234 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1235 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1236 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1237 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1238 static const BYTE detachedSignedBareContent[] = {
1239 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1240 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1241 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1242 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1243 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1244 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1245 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1246 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1247 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1248 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1249 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1250 static const BYTE detachedSignedContent[] = {
1251 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1252 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1253 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1254 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1255 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1256 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1257 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1258 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1259 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1260 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1261 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1262 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1263 static const BYTE signedBareContent[] = {
1264 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1265 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1266 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1267 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1268 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1269 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1270 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1271 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1272 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1273 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1274 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1275 static const BYTE signedContent[] = {
1276 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1277 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1278 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1279 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1280 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1281 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1282 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1283 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1284 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1285 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1286 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1287 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1288 0x0d };
1289 static const BYTE signedHash[] = {
1290 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1291 0x2f };
1292 static const BYTE signedEncodedSigner[] = {
1293 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1294 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1295 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1296 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1297 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1298 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1299 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1300 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1301 static const BYTE signedWithAuthAttrsBareContent[] = {
1302 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1303 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1304 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1305 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1306 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1307 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1308 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1309 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1310 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1311 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1312 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1313 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1314 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1315 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1316 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1317 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1318 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1319 0xff,0xc6,0x33,0x63,0x34 };
1320 static BYTE cert[] = {
1321 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1322 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1323 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1324 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1325 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1326 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1327 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1328 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1329 0xff,0x02,0x01,0x01 };
1330 static BYTE v1CertWithPubKey[] = {
1331 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1332 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1333 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1334 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1335 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1336 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1337 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1338 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1339 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1340 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1341 0x01,0x01 };
1342 static const BYTE signedWithCertEmptyBareContent[] = {
1343 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1344 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1345 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1346 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1347 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1348 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1349 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1350 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1351 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1352 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1353 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1354 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1355 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1356 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1357 static const BYTE signedWithCertBareContent[] = {
1358 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1359 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1360 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1361 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1362 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1363 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1364 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1365 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1366 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1367 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1368 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1369 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1370 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1371 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1372 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1373 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1374 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1375 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1376 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1377 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1378 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1379 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1380 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1381 0x30,0x30,0x30,0x30,0x5a };
1382 static const BYTE signedWithCrlEmptyBareContent[] = {
1383 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1384 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1385 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1386 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1387 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1388 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1389 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1390 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1391 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1392 static const BYTE signedWithCrlBareContent[] = {
1393 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1394 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1395 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1396 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1397 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1398 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1399 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1400 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1401 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1402 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1403 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1404 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1405 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1406 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1407 0xa8,0x0d };
1408 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1409 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1410 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1411 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1412 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1413 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1414 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1415 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1416 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1417 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1418 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1419 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1420 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1421 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1422 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1423 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1424 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1425 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1426 0x04,0x00 };
1427 static const BYTE signedWithCertAndCrlBareContent[] = {
1428 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1429 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1430 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1431 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1432 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1433 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1434 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1435 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1436 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1437 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1438 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1439 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1440 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1441 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1442 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1443 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1444 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1445 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1446 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1447 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1448 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1449 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1450 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1451 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1452 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1453 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1454 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1455 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1456 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1457 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1458 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1459 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1460 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1461 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1462 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1463 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1464 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1465 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1466 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1467 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1468 static BYTE v1CertWithValidPubKey[] = {
1469 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1470 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1471 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1472 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1473 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1474 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1475 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1476 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1477 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1478 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1479 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1480 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1481 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1482 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1483 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1484 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1485 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1486 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1487 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1488 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1489 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1490 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1491 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1492 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1493 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1494 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1495 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1496 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1497 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1498 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1499 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1500 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1501 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1502 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1503 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1504 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1505 0x00 };
1506 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1507 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1508 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1509 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1510 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1511 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1512 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1513 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1514 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1515 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1516 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1517 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1518 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1519 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1520 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1521 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1522 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1523 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1524 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1525 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1526 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1527 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1528 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1529 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1530 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1531 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1532 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1533 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1534
1535 static void test_signed_msg_encoding(void)
1536 {
1537     HCRYPTMSG msg;
1538     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1539     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1540     CERT_INFO certInfo = { 0 };
1541     CERT_BLOB encodedCert = { sizeof(cert), cert };
1542     CRL_BLOB encodedCrl = { sizeof(crl), crl };
1543     char oid_common_name[] = szOID_COMMON_NAME;
1544     CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1545      encodedCommonName };
1546     CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1547     BOOL ret;
1548     HCRYPTKEY key;
1549     DWORD size;
1550
1551     certInfo.SerialNumber.cbData = sizeof(serialNum);
1552     certInfo.SerialNumber.pbData = serialNum;
1553     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1554     certInfo.Issuer.pbData = encodedCommonName;
1555     signer.pCertInfo = &certInfo;
1556     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1557     signInfo.cSigners = 1;
1558     signInfo.rgSigners = &signer;
1559     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1560      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1561     if (!ret && GetLastError() == NTE_EXISTS)
1562         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1563          PROV_RSA_FULL, 0);
1564     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1565     ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1566      0, 0, &key);
1567     ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1568
1569     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1570      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1571     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1572
1573     check_param("detached signed empty bare content", msg,
1574      CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1575      sizeof(signedEmptyBareContent));
1576     check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1577      signedEmptyContent, sizeof(signedEmptyContent));
1578     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1579     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1580     check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1581      signedHash, sizeof(signedHash));
1582     check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1583      detachedSignedBareContent, sizeof(detachedSignedBareContent));
1584     check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1585      detachedSignedContent, sizeof(detachedSignedContent));
1586     SetLastError(0xdeadbeef);
1587     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1588     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1589      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1590     check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1591      signedEncodedSigner, sizeof(signedEncodedSigner));
1592
1593     CryptMsgClose(msg);
1594
1595     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1596      NULL, NULL);
1597     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1598
1599     check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1600      signedEmptyBareContent, sizeof(signedEmptyBareContent));
1601     check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1602      signedEmptyContent, sizeof(signedEmptyContent));
1603     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1604     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1605     check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1606      signedBareContent, sizeof(signedBareContent));
1607     check_param("signed content", msg, CMSG_CONTENT_PARAM,
1608      signedContent, sizeof(signedContent));
1609
1610     CryptMsgClose(msg);
1611
1612     signer.cAuthAttr = 1;
1613     signer.rgAuthAttr = &attr;
1614     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1615      NULL, NULL);
1616     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1617
1618     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1619     check_param("signed with auth attrs bare content", msg,
1620      CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1621      sizeof(signedWithAuthAttrsBareContent));
1622
1623     CryptMsgClose(msg);
1624
1625     signer.cAuthAttr = 0;
1626     signInfo.rgCertEncoded = &encodedCert;
1627     signInfo.cCertEncoded = 1;
1628     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1629      NULL, NULL);
1630     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1631
1632     check_param("signed with cert empty bare content", msg,
1633      CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1634      sizeof(signedWithCertEmptyBareContent));
1635     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1636     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1637     check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1638      signedWithCertBareContent, sizeof(signedWithCertBareContent));
1639
1640     CryptMsgClose(msg);
1641
1642     signInfo.cCertEncoded = 0;
1643     signInfo.rgCrlEncoded = &encodedCrl;
1644     signInfo.cCrlEncoded = 1;
1645     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1646      NULL, NULL);
1647     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1648
1649     check_param("signed with crl empty bare content", msg,
1650      CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1651      sizeof(signedWithCrlEmptyBareContent));
1652     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1653     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1654     check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1655      signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1656
1657     CryptMsgClose(msg);
1658
1659     signInfo.cCertEncoded = 1;
1660     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1661      NULL, NULL);
1662     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1663
1664     check_param("signed with cert and crl empty bare content", msg,
1665      CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1666      sizeof(signedWithCertAndCrlEmptyBareContent));
1667     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1668     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1669     check_param("signed with cert and crl bare content", msg,
1670      CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1671      sizeof(signedWithCertAndCrlBareContent));
1672
1673     CryptMsgClose(msg);
1674
1675     /* Test with a cert with a (bogus) public key */
1676     signInfo.cCrlEncoded = 0;
1677     encodedCert.cbData = sizeof(v1CertWithPubKey);
1678     encodedCert.pbData = v1CertWithPubKey;
1679     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1680      NULL, NULL);
1681     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1682     check_param("signedWithCertWithPubKeyBareContent", msg,
1683      CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1684      sizeof(signedWithCertWithPubKeyBareContent));
1685     CryptMsgClose(msg);
1686
1687     encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1688     encodedCert.pbData = v1CertWithValidPubKey;
1689     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1690      NULL, NULL);
1691     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1692     check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1693      CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1694      sizeof(signedWithCertWithValidPubKeyEmptyContent));
1695     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1696     check_param("signedWithCertWithValidPubKeyContent", msg,
1697      CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1698      sizeof(signedWithCertWithValidPubKeyContent));
1699     CryptMsgClose(msg);
1700
1701     CryptDestroyKey(key);
1702     CryptReleaseContext(signer.hCryptProv, 0);
1703     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1704      CRYPT_DELETEKEYSET);
1705 }
1706
1707 static void test_signed_msg_get_param(void)
1708 {
1709     BOOL ret;
1710     HCRYPTMSG msg;
1711     DWORD size, value = 0;
1712     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1713     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1714     CERT_INFO certInfo = { 0 };
1715
1716     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1717      NULL, NULL);
1718     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1719
1720     /* Content and bare content are always gettable */
1721     size = 0;
1722     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1723     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1724     size = 0;
1725     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1726     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1727     /* For "signed" messages, so is the version. */
1728     size = 0;
1729     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1730     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1731     size = sizeof(value);
1732     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1733     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1734     ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1735     /* But for this message, with no signers, the hash and signer aren't
1736      * available.
1737      */
1738     size = 0;
1739     SetLastError(0xdeadbeef);
1740     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1741     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1742      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1743     SetLastError(0xdeadbeef);
1744     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1745     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1746      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1747     /* As usual, the type isn't available. */
1748     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1749     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1750      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1751
1752     CryptMsgClose(msg);
1753
1754     certInfo.SerialNumber.cbData = sizeof(serialNum);
1755     certInfo.SerialNumber.pbData = serialNum;
1756     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1757     certInfo.Issuer.pbData = encodedCommonName;
1758     signer.pCertInfo = &certInfo;
1759     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1760     signInfo.cSigners = 1;
1761     signInfo.rgSigners = &signer;
1762     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1763      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1764     if (!ret && GetLastError() == NTE_EXISTS)
1765         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1766          PROV_RSA_FULL, 0);
1767     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1768     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1769      NULL, NULL);
1770     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1771
1772     /* This message, with one signer, has the hash and signer for index 0
1773      * available, but not for other indexes.
1774      */
1775     size = 0;
1776     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1777     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1778     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1779     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1780     size = 0;
1781     SetLastError(0xdeadbeef);
1782     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1783     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1784      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1785     SetLastError(0xdeadbeef);
1786     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1787     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1788      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1789     /* As usual, the type isn't available. */
1790     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1791     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1792      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1793
1794     CryptMsgClose(msg);
1795
1796     CryptReleaseContext(signer.hCryptProv, 0);
1797     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1798      PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1799 }
1800
1801 static void test_signed_msg(void)
1802 {
1803     test_signed_msg_open();
1804     test_signed_msg_update();
1805     test_signed_msg_encoding();
1806     test_signed_msg_get_param();
1807 }
1808
1809 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1810 static const struct update_accum a4 = { 1, &b4 };
1811
1812 static const BYTE bogusOIDContent[] = {
1813 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1814 0x04,0x00 };
1815 static const BYTE bogusHashContent[] = {
1816 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1817 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1818 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1819 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1820 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1821
1822 static void test_decode_msg_update(void)
1823 {
1824     HCRYPTMSG msg;
1825     BOOL ret;
1826     CMSG_STREAM_INFO streamInfo = { 0 };
1827     DWORD i;
1828     struct update_accum accum = { 0, NULL };
1829
1830     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1831     /* Update with a full message in a final update */
1832     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1833     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1834     /* Can't update after a final update */
1835     SetLastError(0xdeadbeef);
1836     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1837     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1838      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1839     CryptMsgClose(msg);
1840
1841     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1842     /* Can't send a non-final update without streaming */
1843     SetLastError(0xdeadbeef);
1844     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1845      FALSE);
1846     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1847      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1848     /* A subsequent final update succeeds */
1849     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1850     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1851     CryptMsgClose(msg);
1852
1853     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1854     /* Updating a message that has a NULL stream callback fails */
1855     SetLastError(0xdeadbeef);
1856     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1857      FALSE);
1858     todo_wine
1859     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1860      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1861     /* Changing the callback pointer after the fact yields the same error (so
1862      * the message must copy the stream info, not just store a pointer to it)
1863      */
1864     streamInfo.pfnStreamOutput = nop_stream_output;
1865     SetLastError(0xdeadbeef);
1866     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1867      FALSE);
1868     todo_wine
1869     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1870      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1871     CryptMsgClose(msg);
1872
1873     /* Empty non-final updates are allowed when streaming.. */
1874     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1875     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1876     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1877     /* but final updates aren't when not enough data has been received. */
1878     SetLastError(0xdeadbeef);
1879     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1880     todo_wine
1881     ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1882      "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1883     CryptMsgClose(msg);
1884
1885     /* Updating the message byte by byte is legal */
1886     streamInfo.pfnStreamOutput = accumulating_stream_output;
1887     streamInfo.pvArg = &accum;
1888     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1889     for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1890         ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1891     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1892     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1893     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1894     CryptMsgClose(msg);
1895     todo_wine
1896     check_updates("byte-by-byte empty content", &a4, &accum);
1897     free_updates(&accum);
1898
1899     /* Decoding bogus content fails in non-streaming mode.. */
1900     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1901     SetLastError(0xdeadbeef);
1902     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1903     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1904      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1905     CryptMsgClose(msg);
1906     /* and as the final update in streaming mode.. */
1907     streamInfo.pfnStreamOutput = nop_stream_output;
1908     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1909     SetLastError(0xdeadbeef);
1910     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1911     todo_wine
1912     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1913      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1914     CryptMsgClose(msg);
1915     /* and even as a non-final update in streaming mode. */
1916     streamInfo.pfnStreamOutput = nop_stream_output;
1917     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1918     SetLastError(0xdeadbeef);
1919     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1920     todo_wine
1921     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1922      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1923     CryptMsgClose(msg);
1924
1925     /* An empty message can be opened with indetermined type.. */
1926     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1927     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1928      TRUE);
1929     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1930     /* but decoding it as an explicitly typed message fails. */
1931     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1932      NULL);
1933     SetLastError(0xdeadbeef);
1934     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1935      TRUE);
1936     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1937      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1938     CryptMsgClose(msg);
1939     /* On the other hand, decoding the bare content of an empty message fails
1940      * with unspecified type..
1941      */
1942     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1943     SetLastError(0xdeadbeef);
1944     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1945      sizeof(dataEmptyBareContent), TRUE);
1946     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1947      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1948     CryptMsgClose(msg);
1949     /* but succeeds with explicit type. */
1950     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1951      NULL);
1952     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1953      sizeof(dataEmptyBareContent), TRUE);
1954     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1955     CryptMsgClose(msg);
1956
1957     /* Decoding valid content with an unsupported OID fails */
1958     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1959     SetLastError(0xdeadbeef);
1960     ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
1961     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1962      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1963     CryptMsgClose(msg);
1964
1965     /* Similarly, opening an empty hash with unspecified type succeeds.. */
1966     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1967     SetLastError(0xdeadbeef);
1968     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1969     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1970     CryptMsgClose(msg);
1971     /* while with specified type it fails. */
1972     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1973      NULL);
1974     SetLastError(0xdeadbeef);
1975     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1976     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1977      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1978     CryptMsgClose(msg);
1979     /* On the other hand, decoding the bare content of an empty hash message
1980      * fails with unspecified type..
1981      */
1982     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1983     SetLastError(0xdeadbeef);
1984     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1985      sizeof(hashEmptyBareContent), TRUE);
1986     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1987      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1988     CryptMsgClose(msg);
1989     /* but succeeds with explicit type. */
1990     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1991      NULL);
1992     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1993      sizeof(hashEmptyBareContent), TRUE);
1994     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1995     CryptMsgClose(msg);
1996
1997     /* And again, opening a (non-empty) hash message with unspecified type
1998      * succeeds..
1999      */
2000     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2001     SetLastError(0xdeadbeef);
2002     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2003     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2004     CryptMsgClose(msg);
2005     /* while with specified type it fails.. */
2006     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2007      NULL);
2008     SetLastError(0xdeadbeef);
2009     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2010     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2011      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2012     CryptMsgClose(msg);
2013     /* and decoding the bare content of a non-empty hash message fails with
2014      * unspecified type..
2015      */
2016     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2017     SetLastError(0xdeadbeef);
2018     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2019     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2020      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2021     CryptMsgClose(msg);
2022     /* but succeeds with explicit type. */
2023     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2024      NULL);
2025     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2026     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2027     CryptMsgClose(msg);
2028
2029     /* Opening a (non-empty) hash message with unspecified type and a bogus
2030      * hash value succeeds..
2031      */
2032     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2033     SetLastError(0xdeadbeef);
2034     ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2035     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2036     CryptMsgClose(msg);
2037
2038     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2039     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2040     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2041     CryptMsgClose(msg);
2042     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2043     SetLastError(0xdeadbeef);
2044     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2045      sizeof(signedWithCertAndCrlBareContent), TRUE);
2046     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2047      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2048     CryptMsgClose(msg);
2049     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2050      NULL);
2051     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2052      sizeof(signedWithCertAndCrlBareContent), TRUE);
2053     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2054     CryptMsgClose(msg);
2055 }
2056
2057 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2058  0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2059
2060 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2061  const CMSG_SIGNER_INFO *expected)
2062 {
2063     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2064      expected->dwVersion, got->dwVersion);
2065     ok(got->Issuer.cbData == expected->Issuer.cbData,
2066      "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2067      got->Issuer.cbData);
2068     ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2069      "Unexpected issuer\n");
2070     ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2071      "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2072      got->SerialNumber.cbData);
2073     ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2074      got->SerialNumber.cbData), "Unexpected serial number\n");
2075     /* FIXME: check more things */
2076 }
2077
2078 static const BYTE signedWithCertAndCrlComputedHash[] = {
2079 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2080 0x2f };
2081
2082 static void test_decode_msg_get_param(void)
2083 {
2084     HCRYPTMSG msg;
2085     BOOL ret;
2086     DWORD size = 0, value;
2087     LPBYTE buf;
2088
2089     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2090     SetLastError(0xdeadbeef);
2091     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2092     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2093      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2094     ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2095     check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2096      sizeof(msgData));
2097     CryptMsgClose(msg);
2098
2099     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2100     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2101     check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2102     check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2103     check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2104      emptyHashParam, sizeof(emptyHashParam));
2105     CryptMsgClose(msg);
2106     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2107     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2108     check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2109      sizeof(msgData));
2110     check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2111      sizeof(hashParam));
2112     check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2113      hashParam, sizeof(hashParam));
2114     /* Curiously, getting the hash of index 1 succeeds, even though there's
2115      * only one hash.
2116      */
2117     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2118     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2119     buf = CryptMemAlloc(size);
2120     if (buf)
2121     {
2122         ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2123         ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2124         ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2125         CryptMemFree(buf);
2126     }
2127     check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2128      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2129     value = CMSG_HASHED_DATA_V0;
2130     check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2131      sizeof(value));
2132     CryptMsgClose(msg);
2133
2134     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2135     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2136     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2137     check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2138      sizeof(msgData));
2139     check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2140      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2141     size = sizeof(value);
2142     value = 2112;
2143     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2144     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2145     ok(value == 1, "Expected 1 signer, got %d\n", value);
2146     size = 0;
2147     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2148     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2149     if (ret)
2150         buf = CryptMemAlloc(size);
2151     else
2152         buf = NULL;
2153     if (buf)
2154     {
2155         CMSG_SIGNER_INFO signer = { 0 };
2156
2157         signer.dwVersion = 1;
2158         signer.Issuer.cbData = sizeof(encodedCommonName);
2159         signer.Issuer.pbData = encodedCommonName;
2160         signer.SerialNumber.cbData = sizeof(serialNum);
2161         signer.SerialNumber.pbData = serialNum;
2162         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2163         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2164         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2165         CryptMemFree(buf);
2166     }
2167     /* index is ignored when getting signer count */
2168     size = sizeof(value);
2169     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2170     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2171     ok(value == 1, "Expected 1 signer, got %d\n", value);
2172     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2173     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2174     ok(value == 0, "Expected 0 certs, got %d\n", value);
2175     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2176     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2177     ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2178     CryptMsgClose(msg);
2179     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2180      NULL);
2181     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2182      sizeof(signedWithCertAndCrlBareContent), TRUE);
2183     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2184     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2185     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2186     ok(value == 1, "Expected 1 cert, got %d\n", value);
2187     check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2188     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2189     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2190     ok(value == 1, "Expected 1 CRL, got %d\n", value);
2191     check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2192     check_param("signed with cert and CRL computed hash", msg,
2193      CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2194      sizeof(signedWithCertAndCrlComputedHash));
2195     CryptMsgClose(msg);
2196 }
2197
2198 static void test_decode_msg(void)
2199 {
2200     test_decode_msg_update();
2201     test_decode_msg_get_param();
2202 }
2203
2204 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2205 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2206 static BYTE encodedPubKey[] = {
2207 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2208 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2209 0x0d,0x0e,0x0f };
2210 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2211 static BYTE mod_encoded[] = {
2212  0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2213  0x01,0x00,0x01 };
2214
2215 static void test_msg_control(void)
2216 {
2217     static char oid_rsa_rsa[] = szOID_RSA_RSA;
2218     BOOL ret;
2219     HCRYPTMSG msg;
2220     DWORD i;
2221     CERT_INFO certInfo = { 0 };
2222     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2223     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2224     CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2225
2226     /* Crashes
2227     ret = CryptMsgControl(NULL, 0, 0, NULL);
2228     */
2229
2230     /* Data encode messages don't allow any sort of control.. */
2231     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2232      NULL);
2233     /* either with no prior update.. */
2234     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2235     {
2236         SetLastError(0xdeadbeef);
2237         ret = CryptMsgControl(msg, 0, i, NULL);
2238         ok(!ret && GetLastError() == E_INVALIDARG,
2239          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2240     }
2241     /* or after an update. */
2242     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2243     {
2244         SetLastError(0xdeadbeef);
2245         ret = CryptMsgControl(msg, 0, i, NULL);
2246         ok(!ret && GetLastError() == E_INVALIDARG,
2247          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2248     }
2249     CryptMsgClose(msg);
2250
2251     /* Hash encode messages don't allow any sort of control.. */
2252     hashInfo.cbSize = sizeof(hashInfo);
2253     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2254     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2255      NULL, NULL);
2256     /* either with no prior update.. */
2257     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2258     {
2259         SetLastError(0xdeadbeef);
2260         ret = CryptMsgControl(msg, 0, i, NULL);
2261         ok(!ret && GetLastError() == E_INVALIDARG,
2262          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2263     }
2264     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2265     /* or after an update. */
2266     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2267     {
2268         SetLastError(0xdeadbeef);
2269         ret = CryptMsgControl(msg, 0, i, NULL);
2270         ok(!ret && GetLastError() == E_INVALIDARG,
2271          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2272     }
2273     CryptMsgClose(msg);
2274
2275     /* Signed encode messages likewise don't allow any sort of control.. */
2276     signInfo.cbSize = sizeof(signInfo);
2277     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2278      NULL, NULL);
2279     /* either before an update.. */
2280     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2281     {
2282         SetLastError(0xdeadbeef);
2283         ret = CryptMsgControl(msg, 0, i, NULL);
2284         ok(!ret && GetLastError() == E_INVALIDARG,
2285          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2286     }
2287     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2288     /* or after an update. */
2289     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2290     {
2291         SetLastError(0xdeadbeef);
2292         ret = CryptMsgControl(msg, 0, i, NULL);
2293         ok(!ret && GetLastError() == E_INVALIDARG,
2294          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2295     }
2296     CryptMsgClose(msg);
2297
2298     /* Decode messages behave a bit differently. */
2299     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2300     /* Bad control type */
2301     SetLastError(0xdeadbeef);
2302     ret = CryptMsgControl(msg, 0, 0, NULL);
2303     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2304      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2305     SetLastError(0xdeadbeef);
2306     ret = CryptMsgControl(msg, 1, 0, NULL);
2307     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2308      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2309     /* Can't verify the hash of an indeterminate-type message */
2310     SetLastError(0xdeadbeef);
2311     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2312     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2313      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2314     /* Crashes
2315     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2316      */
2317     /* Can't decrypt an indeterminate-type message */
2318     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2319     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2320      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2321     CryptMsgClose(msg);
2322
2323     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2324      NULL);
2325     /* Can't verify the hash of an empty message */
2326     SetLastError(0xdeadbeef);
2327     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2328     todo_wine
2329     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2330      "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2331     /* Crashes
2332     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2333      */
2334     /* Can't verify the signature of a hash message */
2335     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2336     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2337      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2338     CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2339      TRUE);
2340     /* Oddly enough, this fails */
2341     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2342     todo_wine
2343     ok(!ret, "Expected failure\n");
2344     CryptMsgClose(msg);
2345     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2346      NULL);
2347     CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2348     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2349     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2350     /* Can't decrypt an indeterminate-type message */
2351     SetLastError(0xdeadbeef);
2352     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2353     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2354      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2355     CryptMsgClose(msg);
2356
2357     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2358      NULL);
2359     /* Can't verify the hash of a signed message */
2360     SetLastError(0xdeadbeef);
2361     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2362     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2363      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2364     /* Can't decrypt a signed message */
2365     SetLastError(0xdeadbeef);
2366     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2367     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2368      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2369     /* Crash
2370     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2371     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2372      */
2373     CryptMsgUpdate(msg, signedWithCertBareContent,
2374      sizeof(signedWithCertBareContent), TRUE);
2375     /* With an empty cert info, the signer can't be found in the message (and
2376      * the signature can't be verified.
2377      */
2378     SetLastError(0xdeadbeef);
2379     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2380     ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2381      "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2382     /* The cert info is expected to have an issuer, serial number, and public
2383      * key info set.
2384      */
2385     certInfo.SerialNumber.cbData = sizeof(serialNum);
2386     certInfo.SerialNumber.pbData = serialNum;
2387     certInfo.Issuer.cbData = sizeof(encodedCommonName);
2388     certInfo.Issuer.pbData = encodedCommonName;
2389     SetLastError(0xdeadbeef);
2390     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2391     ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2392      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2393     CryptMsgClose(msg);
2394     /* This cert has a public key, but it's not in a usable form */
2395     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2396      NULL);
2397     CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2398      sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2399     /* Again, cert info needs to have a public key set */
2400     SetLastError(0xdeadbeef);
2401     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2402     ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2403      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2404     /* The public key is supposed to be in encoded form.. */
2405     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2406     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2407     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2408     SetLastError(0xdeadbeef);
2409     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2410     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2411      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2412     /* but not as a X509_PUBLIC_KEY_INFO.. */
2413     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2414     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2415     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2416     SetLastError(0xdeadbeef);
2417     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2418     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2419      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2420     /* This decodes successfully, but it doesn't match any key in the message */
2421     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2422     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2423     SetLastError(0xdeadbeef);
2424     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2425     /* In Wine's rsaenh, this fails to decode because the key length is too
2426      * small.  Not sure if that's a bug in rsaenh, so leaving todo_wine for
2427      * now.
2428      */
2429     todo_wine
2430     ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2431      "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2432     CryptMsgClose(msg);
2433     /* A message with no data doesn't have a valid signature */
2434     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2435     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2436      sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2437     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2438     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2439     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2440     SetLastError(0xdeadbeef);
2441     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2442     ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2443      "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2444     CryptMsgClose(msg);
2445     /* Finally, this succeeds */
2446     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2447     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2448      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2449     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2450     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2451 }
2452
2453 static void test_msg_get_signer_count(void)
2454 {
2455     LONG count;
2456
2457     SetLastError(0xdeadbeef);
2458     count = CryptGetMessageSignerCount(0, NULL, 0);
2459     ok(count == -1, "Expected -1, got %d\n", count);
2460     ok(GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n",
2461      GetLastError());
2462     SetLastError(0xdeadbeef);
2463     count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, NULL, 0);
2464     ok(count == -1, "Expected -1, got %d\n", count);
2465     ok(GetLastError() == CRYPT_E_ASN1_EOD,
2466      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2467     SetLastError(0xdeadbeef);
2468     count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2469      dataEmptyBareContent, sizeof(dataEmptyBareContent));
2470     ok(count == -1, "Expected -1, got %d\n", count);
2471     ok(GetLastError() == CRYPT_E_ASN1_BADTAG,
2472      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2473     SetLastError(0xdeadbeef);
2474     count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2475      dataEmptyContent, sizeof(dataEmptyContent));
2476     ok(count == -1, "Expected -1, got %d\n", count);
2477     ok(GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2478      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2479     SetLastError(0xdeadbeef);
2480     count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2481      signedEmptyBareContent, sizeof(signedEmptyBareContent));
2482     ok(count == -1, "Expected -1, got %d\n", count);
2483     ok(GetLastError() == CRYPT_E_ASN1_BADTAG,
2484      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2485     count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2486      signedEmptyContent, sizeof(signedEmptyContent));
2487     ok(count == 1, "Expected 1, got %d\n", count);
2488 }
2489
2490 static const BYTE signedWithCertEmptyContent[] = {
2491 0x30,0x81,0xdf,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
2492 0x81,0xd1,0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
2493 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,
2494 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2495 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2496 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2497 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2498 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2499 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2500 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
2501 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2502 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
2503 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
2504 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
2505 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
2506 0x00 };
2507 static const BYTE signedWithCertContent[] = {
2508 0x30,0x82,0x01,0x32,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
2509 0xa0,0x82,0x01,0x23,0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
2510 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
2511 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
2512 0x02,0x03,0x04,0xa0,0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
2513 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
2514 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
2515 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
2516 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
2517 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
2518 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
2519 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
2520 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,
2521 0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,
2522 0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,
2523 0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,
2524 0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,
2525 0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,
2526 0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,
2527 0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,
2528 0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
2529 static const BYTE signedWithCertWithPubKeyContent[] = {
2530 0x30,0x81,0xfc,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
2531 0x81,0xee,0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
2532 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,
2533 0x98,0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,
2534 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
2535 0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2536 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
2537 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,
2538 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2539 0x6e,0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2540 0x01,0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
2541 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,
2542 0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,
2543 0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
2544 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2545 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
2546 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
2547
2548 static void test_verify_message_signature(void)
2549 {
2550     BOOL ret;
2551     CRYPT_VERIFY_MESSAGE_PARA para = { 0 };
2552     PCCERT_CONTEXT cert;
2553     DWORD cbDecoded;
2554
2555     SetLastError(0xdeadbeef);
2556     ret = CryptVerifyMessageSignature(NULL, 0, NULL, 0, NULL, 0, NULL);
2557     ok(!ret && GetLastError() == E_INVALIDARG,
2558      "Expected E_INVALIDARG, got %08x\n", GetLastError());
2559     SetLastError(0xdeadbeef);
2560     ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2561     ok(!ret && GetLastError() == E_INVALIDARG,
2562      "Expected E_INVALIDARG, got %08x\n", GetLastError());
2563     para.cbSize = sizeof(para);
2564     SetLastError(0xdeadbeef);
2565     ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2566     ok(!ret && GetLastError() == E_INVALIDARG,
2567      "Expected E_INVALIDARG, got %08x\n", GetLastError());
2568     para.cbSize = 0;
2569     para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING;
2570     SetLastError(0xdeadbeef);
2571     ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2572     ok(!ret && GetLastError() == E_INVALIDARG,
2573      "Expected E_INVALIDARG, got %08x\n", GetLastError());
2574     para.cbSize = sizeof(para);
2575     SetLastError(0xdeadbeef);
2576     ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2577     ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2578      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2579     /* Check whether cert is set on error */
2580     cert = (PCCERT_CONTEXT)0xdeadbeef;
2581     ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, &cert);
2582     ok(cert == NULL, "Expected NULL cert\n");
2583     /* Check whether cbDecoded is set on error */
2584     cbDecoded = 0xdeadbeef;
2585     ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, &cbDecoded,
2586      NULL);
2587     ok(!cbDecoded, "Expected 0\n");
2588     SetLastError(0xdeadbeef);
2589     ret = CryptVerifyMessageSignature(&para, 0, dataEmptyBareContent,
2590      sizeof(dataEmptyBareContent), NULL, 0, NULL);
2591     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2592      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2593     SetLastError(0xdeadbeef);
2594     ret = CryptVerifyMessageSignature(&para, 0, dataEmptyContent,
2595      sizeof(dataEmptyContent), NULL, 0, NULL);
2596     ok(!ret && GetLastError() == CRYPT_E_UNEXPECTED_MSG_TYPE,
2597      "Expected CRYPT_E_UNEXPECTED_MSG_TYPE, got %08x\n", GetLastError());
2598     SetLastError(0xdeadbeef);
2599     ret = CryptVerifyMessageSignature(&para, 0, signedEmptyBareContent,
2600      sizeof(signedEmptyBareContent), NULL, 0, NULL);
2601     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2602      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2603     SetLastError(0xdeadbeef);
2604     ret = CryptVerifyMessageSignature(&para, 0, signedEmptyContent,
2605      sizeof(signedEmptyContent), NULL, 0, NULL);
2606     ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2607      "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2608     SetLastError(0xdeadbeef);
2609     ret = CryptVerifyMessageSignature(&para, 0, signedContent,
2610      sizeof(signedContent), NULL, 0, NULL);
2611     ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2612      "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2613     /* FIXME: Windows fails with CRYPT_E_NOT_FOUND for these messages, but
2614      * their signer certs have invalid public keys that fail to decode.  In
2615      * Wine therefore the failure is an ASN error.  Need some messages with
2616      * valid public keys and invalid signatures to check against.
2617      */
2618     ret = CryptVerifyMessageSignature(&para, 0, signedWithCertEmptyContent,
2619      sizeof(signedWithCertEmptyContent), NULL, 0, NULL);
2620     ok(!ret, "Expected failure\n");
2621     ret = CryptVerifyMessageSignature(&para, 0, signedWithCertContent,
2622      sizeof(signedWithCertContent), NULL, 0, NULL);
2623     ok(!ret, "Expected failure\n");
2624     ret = CryptVerifyMessageSignature(&para, 0, signedWithCertWithPubKeyContent,
2625      sizeof(signedWithCertWithPubKeyContent), NULL, 0, NULL);
2626     ok(!ret, "Expected failure\n");
2627 }
2628
2629 START_TEST(msg)
2630 {
2631      init_function_pointers();
2632
2633     /* Basic parameter checking tests */
2634     test_msg_open_to_encode();
2635     test_msg_open_to_decode();
2636     test_msg_get_param();
2637     test_msg_close();
2638     test_msg_control();
2639
2640     /* Message-type specific tests */
2641     test_data_msg();
2642     test_hash_msg();
2643     test_signed_msg();
2644     test_decode_msg();
2645
2646     /* simplified message functions */
2647     test_msg_get_signer_count();
2648     test_verify_message_signature();
2649 }