urlmon: LockModule in create_binding_protocol as we ReleaseModule when the object...
[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 void test_msg_open_to_encode(void)
33 {
34     HCRYPTMSG msg;
35
36     /* Crash
37     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
38      NULL, NULL);
39     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
40      NULL);
41     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
42      NULL);
43      */
44
45     /* Bad encodings */
46     SetLastError(0xdeadbeef);
47     msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
48     ok(!msg && GetLastError() == E_INVALIDARG,
49      "Expected E_INVALIDARG, got %x\n", GetLastError());
50     SetLastError(0xdeadbeef);
51     msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
52     ok(!msg && GetLastError() == E_INVALIDARG,
53      "Expected E_INVALIDARG, got %x\n", GetLastError());
54
55     /* Bad message types */
56     SetLastError(0xdeadbeef);
57     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
58     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
59      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
60     SetLastError(0xdeadbeef);
61     msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
62      NULL, NULL, NULL);
63     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
64      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
65     SetLastError(0xdeadbeef);
66     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
67      CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
68     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
69      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
70     SetLastError(0xdeadbeef);
71     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
72      NULL, NULL);
73     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
74      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
75 }
76
77 static void test_msg_open_to_decode(void)
78 {
79     HCRYPTMSG msg;
80     CMSG_STREAM_INFO streamInfo = { 0 };
81
82     SetLastError(0xdeadbeef);
83     msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
84     ok(!msg && GetLastError() == E_INVALIDARG,
85      "Expected E_INVALIDARG, got %x\n", GetLastError());
86
87     /* Bad encodings */
88     SetLastError(0xdeadbeef);
89     msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
90     ok(!msg && GetLastError() == E_INVALIDARG,
91      "Expected E_INVALIDARG, got %x\n", GetLastError());
92     SetLastError(0xdeadbeef);
93     msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
94     ok(!msg && GetLastError() == E_INVALIDARG,
95      "Expected E_INVALIDARG, got %x\n", GetLastError());
96
97     /* The message type can be explicit... */
98     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
99      NULL);
100     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
101     CryptMsgClose(msg);
102     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
103      NULL);
104     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
105     CryptMsgClose(msg);
106     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
107      NULL);
108     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
109     CryptMsgClose(msg);
110     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
111      NULL);
112     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
113     CryptMsgClose(msg);
114     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
115      CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
116     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
117     CryptMsgClose(msg);
118     /* or implicit.. */
119     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
120     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
121     CryptMsgClose(msg);
122     /* or even invalid. */
123     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
124      NULL);
125     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
126     CryptMsgClose(msg);
127     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
128     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
129     CryptMsgClose(msg);
130
131     /* And even though the stream info parameter "must be set to NULL" for
132      * CMSG_HASHED, it's still accepted.
133      */
134     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
135      &streamInfo);
136     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
137     CryptMsgClose(msg);
138 }
139
140 static void test_msg_get_param(void)
141 {
142     BOOL ret;
143     HCRYPTMSG msg;
144     DWORD size, i, value;
145     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
146     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
147
148     /* Crash
149     ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
150     ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
151     ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
152      */
153
154     /* Decoded messages */
155     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
156     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
157     /* For decoded messages, the type is always available */
158     size = 0;
159     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
160     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
161     size = sizeof(value);
162     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
163     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
164     /* For this (empty) message, the type isn't set */
165     ok(value == 0, "Expected type 0, got %d\n", value);
166     CryptMsgClose(msg);
167
168     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
169      NULL);
170     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
171     /* For explicitly typed messages, the type is known. */
172     size = sizeof(value);
173     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
174     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
175     ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
176     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
177     {
178         size = 0;
179         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
180         ok(!ret, "Parameter %d: expected failure\n", i);
181     }
182     CryptMsgClose(msg);
183
184     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
185      NULL);
186     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
187     size = sizeof(value);
188     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
189     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
190     ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
191     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
192     {
193         size = 0;
194         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
195         ok(!ret, "Parameter %d: expected failure\n", i);
196     }
197     CryptMsgClose(msg);
198
199     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
200      NULL);
201     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
202     size = sizeof(value);
203     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
204     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
205     ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
206     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
207     {
208         size = 0;
209         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
210         ok(!ret, "Parameter %d: expected failure\n", i);
211     }
212     CryptMsgClose(msg);
213
214     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
215      NULL);
216     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
217     size = sizeof(value);
218     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
219     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
220     ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
221     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
222     {
223         size = 0;
224         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
225         ok(!ret, "Parameter %d: expected failure\n", i);
226     }
227     CryptMsgClose(msg);
228
229     /* Explicitly typed messages get their types set, even if they're invalid */
230     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
231      NULL);
232     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
233     size = sizeof(value);
234     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
235     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
236     ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
237     CryptMsgClose(msg);
238
239     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
240     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
241     size = sizeof(value);
242     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
243     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
244     ok(value == 1000, "Expected 1000, got %d\n", value);
245     CryptMsgClose(msg);
246 }
247
248 static void test_msg_close(void)
249 {
250     BOOL ret;
251     HCRYPTMSG msg;
252
253     /* NULL succeeds.. */
254     ret = CryptMsgClose(NULL);
255     ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
256     /* but an arbitrary pointer crashes. */
257     if (0)
258         ret = CryptMsgClose((HCRYPTMSG)1);
259     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
260      NULL);
261     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
262     ret = CryptMsgClose(msg);
263     ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
264 }
265
266 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
267  const BYTE *expected, DWORD expectedSize)
268 {
269     DWORD size;
270     LPBYTE buf;
271     BOOL ret;
272
273     size = 0xdeadbeef;
274     ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
275     ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
276     buf = HeapAlloc(GetProcessHeap(), 0, size);
277     ret = CryptMsgGetParam(msg, param, 0, buf, &size);
278     ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
279     ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
280      expectedSize, size);
281     if (size == expectedSize && size)
282         ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
283     HeapFree(GetProcessHeap(), 0, buf);
284 }
285
286 static void test_data_msg_open(void)
287 {
288     HCRYPTMSG msg;
289     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
290     CMSG_STREAM_INFO streamInfo = { 0 };
291     char oid[] = "1.2.3";
292
293     /* The data message type takes no additional info */
294     SetLastError(0xdeadbeef);
295     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
296      NULL, NULL);
297     ok(!msg && GetLastError() == E_INVALIDARG,
298      "Expected E_INVALIDARG, got %x\n", GetLastError());
299     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
300      NULL);
301     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
302     CryptMsgClose(msg);
303
304     /* An empty stream info is allowed. */
305     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
306      &streamInfo);
307     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
308     CryptMsgClose(msg);
309
310     /* Passing a bogus inner OID succeeds for a non-streamed message.. */
311     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
312      NULL);
313     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
314     CryptMsgClose(msg);
315     /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
316     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
317      CMSG_DATA, NULL, oid, NULL);
318     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
319     CryptMsgClose(msg);
320     /* and when a stream info is given, even though you're not supposed to be
321      * able to use anything but szOID_RSA_data when streaming is being used.
322      */
323     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
324      CMSG_DATA, NULL, oid, &streamInfo);
325     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
326     CryptMsgClose(msg);
327 }
328
329 static const BYTE msgData[] = { 1, 2, 3, 4 };
330
331 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
332  BOOL final)
333 {
334     return TRUE;
335 }
336
337 static void test_data_msg_update(void)
338 {
339     HCRYPTMSG msg;
340     BOOL ret;
341     CMSG_STREAM_INFO streamInfo = { 0 };
342
343     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
344      NULL);
345     /* Can't update a message that wasn't opened detached with final = FALSE */
346     SetLastError(0xdeadbeef);
347     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
348     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
349      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
350     /* Updating it with final = TRUE succeeds */
351     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
352     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
353     /* Any subsequent update will fail, as the last was final */
354     SetLastError(0xdeadbeef);
355     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
356     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
357      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
358     CryptMsgClose(msg);
359
360     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
361      NULL);
362     /* Can't update a message with no data */
363     SetLastError(0xdeadbeef);
364     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
365     ok(!ret && GetLastError() == E_INVALIDARG,
366      "Expected E_INVALIDARG, got %x\n", GetLastError());
367     /* Curiously, a valid update will now fail as well, presumably because of
368      * the last (invalid, but final) update.
369      */
370     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
371     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
372      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
373     CryptMsgClose(msg);
374
375     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
376      CMSG_DATA, NULL, NULL, NULL);
377     /* Doesn't appear to be able to update CMSG-DATA with non-final updates */
378     SetLastError(0xdeadbeef);
379     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
380     ok(!ret && GetLastError() == E_INVALIDARG,
381      "Expected E_INVALIDARG, got %x\n", GetLastError());
382     SetLastError(0xdeadbeef);
383     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
384     ok(!ret && GetLastError() == E_INVALIDARG,
385      "Expected E_INVALIDARG, got %x\n", GetLastError());
386     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
387     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
388     CryptMsgClose(msg);
389
390     /* Calling update after opening with an empty stream info (with a bogus
391      * output function) yields an error:
392      */
393     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
394      &streamInfo);
395     SetLastError(0xdeadbeef);
396     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
397     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
398      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
399     CryptMsgClose(msg);
400     /* Calling update with a valid output function succeeds, even if the data
401      * exceeds the size specified in the stream info.
402      */
403     streamInfo.pfnStreamOutput = nop_stream_output;
404     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
405      &streamInfo);
406     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
407     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
408     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
409     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
410     CryptMsgClose(msg);
411 }
412
413 static void test_data_msg_get_param(void)
414 {
415     HCRYPTMSG msg;
416     DWORD size;
417     BOOL ret;
418     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
419
420     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
421      NULL);
422
423     /* Content and bare content are always gettable when not streaming */
424     size = 0;
425     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
426     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
427     size = 0;
428     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
429     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
430     /* But for this type of message, the signer and hash aren't applicable,
431      * and the type isn't available.
432      */
433     size = 0;
434     SetLastError(0xdeadbeef);
435     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
436     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
437      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
438     SetLastError(0xdeadbeef);
439     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
440     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
441      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
442     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
443     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
444      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
445     CryptMsgClose(msg);
446
447     /* Can't get content or bare content when streaming */
448     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
449      NULL, &streamInfo);
450     SetLastError(0xdeadbeef);
451     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
452     ok(!ret && GetLastError() == E_INVALIDARG,
453      "Expected E_INVALIDARG, got %x\n", GetLastError());
454     SetLastError(0xdeadbeef);
455     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
456     ok(!ret && GetLastError() == E_INVALIDARG,
457      "Expected E_INVALIDARG, got %x\n", GetLastError());
458     CryptMsgClose(msg);
459 }
460
461 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
462 static const BYTE dataEmptyContent[] = {
463 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
464 0x04,0x00 };
465 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
466 static const BYTE dataContent[] = {
467 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
468 0x04,0x04,0x01,0x02,0x03,0x04 };
469
470 struct update_accum
471 {
472     DWORD cUpdates;
473     CRYPT_DATA_BLOB *updates;
474 };
475
476 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
477  DWORD cb, BOOL final)
478 {
479     struct update_accum *accum = (struct update_accum *)pvArg;
480     BOOL ret = FALSE;
481
482     if (accum->cUpdates)
483         accum->updates = CryptMemRealloc(accum->updates,
484          (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
485     else
486         accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
487     if (accum->updates)
488     {
489         CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
490
491         blob->pbData = CryptMemAlloc(cb);
492         if (blob->pbData)
493         {
494             memcpy(blob->pbData, pb, cb);
495             blob->cbData = cb;
496             ret = TRUE;
497         }
498         accum->cUpdates++;
499     }
500     return ret;
501 }
502
503 /* The updates of a (bogus) definite-length encoded message */
504 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
505  0x07,0x01,0xa0,0x02,0x04,0x00 };
506 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
507 static CRYPT_DATA_BLOB b1[] = {
508     { sizeof(u1), u1 },
509     { sizeof(u2), u2 },
510     { sizeof(u2), u2 },
511 };
512 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
513 /* The updates of a definite-length encoded message */
514 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
515  0x07,0x01,0xa0,0x06,0x04,0x04 };
516 static CRYPT_DATA_BLOB b2[] = {
517     { sizeof(u3), u3 },
518     { sizeof(u2), u2 },
519 };
520 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
521 /* The updates of an indefinite-length encoded message */
522 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
523  0x07,0x01,0xa0,0x80,0x24,0x80 };
524 static BYTE u5[] = { 0x04,0x04 };
525 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
526 static CRYPT_DATA_BLOB b3[] = {
527     { sizeof(u4), u4 },
528     { sizeof(u5), u5 },
529     { sizeof(u2), u2 },
530     { sizeof(u5), u5 },
531     { sizeof(u2), u2 },
532     { sizeof(u6), u6 },
533 };
534 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
535
536 static void check_updates(LPCSTR header, const struct update_accum *expected,
537  const struct update_accum *got)
538 {
539     DWORD i;
540
541     ok(expected->cUpdates == got->cUpdates,
542      "%s: expected %d updates, got %d\n", header, expected->cUpdates,
543      got->cUpdates);
544     if (expected->cUpdates == got->cUpdates)
545         for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
546         {
547             ok(expected->updates[i].cbData == got->updates[i].cbData,
548              "%s, update %d: expected %d bytes, got %d\n", header, i,
549              expected->updates[i].cbData, got->updates[i].cbData);
550             if (expected->updates[i].cbData && expected->updates[i].cbData ==
551              got->updates[i].cbData)
552                 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
553                  got->updates[i].cbData), "%s, update %d: unexpected value\n",
554                  header, i);
555         }
556 }
557
558 /* Frees the updates stored in accum */
559 static void free_updates(struct update_accum *accum)
560 {
561     DWORD i;
562
563     for (i = 0; i < accum->cUpdates; i++)
564         CryptMemFree(accum->updates[i].pbData);
565     CryptMemFree(accum->updates);
566     accum->updates = NULL;
567     accum->cUpdates = 0;
568 }
569
570 static void test_data_msg_encoding(void)
571 {
572     HCRYPTMSG msg;
573     BOOL ret;
574     static char oid[] = "1.2.3";
575     struct update_accum accum = { 0, NULL };
576     CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
577
578     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
579      NULL);
580     check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
581      dataEmptyBareContent, sizeof(dataEmptyBareContent));
582     check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
583      sizeof(dataEmptyContent));
584     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
585     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
586     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
587      dataBareContent, sizeof(dataBareContent));
588     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
589      sizeof(dataContent));
590     CryptMsgClose(msg);
591     /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
592     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
593      CMSG_DATA, NULL, NULL, NULL);
594     check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
595      dataEmptyBareContent, sizeof(dataEmptyBareContent));
596     check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
597      sizeof(dataEmptyContent));
598     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
599     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
600     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
601      dataBareContent, sizeof(dataBareContent));
602     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
603      sizeof(dataContent));
604     CryptMsgClose(msg);
605     /* The inner OID is apparently ignored */
606     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
607      NULL);
608     check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
609      dataEmptyBareContent, sizeof(dataEmptyBareContent));
610     check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
611      dataEmptyContent, sizeof(dataEmptyContent));
612     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
613     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
614     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
615      dataBareContent, sizeof(dataBareContent));
616     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
617      sizeof(dataContent));
618     CryptMsgClose(msg);
619     /* A streaming message is DER encoded if the length is not 0xffffffff, but
620      * curiously, updates aren't validated to make sure they don't exceed the
621      * stated length.  (The resulting output will of course fail to decode.)
622      */
623     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
624      NULL, &streamInfo);
625     CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
626     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
627     CryptMsgClose(msg);
628     check_updates("bogus data message with definite length", &a1, &accum);
629     free_updates(&accum);
630     /* A valid definite-length encoding: */
631     streamInfo.cbContent = sizeof(msgData);
632     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
633      NULL, &streamInfo);
634     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
635     CryptMsgClose(msg);
636     check_updates("data message with definite length", &a2, &accum);
637     free_updates(&accum);
638     /* An indefinite-length encoding: */
639     streamInfo.cbContent = 0xffffffff;
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     todo_wine
646     check_updates("data message with indefinite length", &a3, &accum);
647     free_updates(&accum);
648 }
649
650 static void test_data_msg(void)
651 {
652     test_data_msg_open();
653     test_data_msg_update();
654     test_data_msg_get_param();
655     test_data_msg_encoding();
656 }
657
658 static void test_hash_msg_open(void)
659 {
660     HCRYPTMSG msg;
661     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
662     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
663
664     SetLastError(0xdeadbeef);
665     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
666      NULL, NULL);
667     ok(!msg && GetLastError() == E_INVALIDARG,
668      "Expected E_INVALIDARG, got %x\n", GetLastError());
669     hashInfo.cbSize = sizeof(hashInfo);
670     SetLastError(0xdeadbeef);
671     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
672      NULL, NULL);
673     ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
674      "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
675     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
676     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
677      NULL, NULL);
678     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
679     CryptMsgClose(msg);
680     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
681      CMSG_HASHED, &hashInfo, NULL, NULL);
682     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
683     CryptMsgClose(msg);
684     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
685      CMSG_HASHED, &hashInfo, NULL, &streamInfo);
686     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
687     CryptMsgClose(msg);
688 }
689
690 static void test_hash_msg_update(void)
691 {
692     HCRYPTMSG msg;
693     BOOL ret;
694     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
695      { oid_rsa_md5, { 0, NULL } }, NULL };
696     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
697
698     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
699      CMSG_HASHED, &hashInfo, NULL, NULL);
700     /* Detached hashed messages opened in non-streaming mode allow non-final
701      * updates..
702      */
703     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
704     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
705     /* including non-final updates with no data.. */
706     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
707     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
708     /* and final updates with no data. */
709     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
710     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
711     /* But no updates are allowed after the final update. */
712     SetLastError(0xdeadbeef);
713     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
714     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
715      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
716     SetLastError(0xdeadbeef);
717     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
718     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
719      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
720     CryptMsgClose(msg);
721     /* Non-detached messages, in contrast, don't allow non-final updates in
722      * non-streaming mode.
723      */
724     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
725      NULL, NULL);
726     SetLastError(0xdeadbeef);
727     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
728     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
729      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
730     /* Final updates (including empty ones) are allowed. */
731     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
732     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
733     CryptMsgClose(msg);
734     /* And, of course, streaming mode allows non-final updates */
735     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
736      NULL, &streamInfo);
737     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
738     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
739     CryptMsgClose(msg);
740     /* Setting pfnStreamOutput to NULL results in no error.  (In what appears
741      * to be a bug, it isn't actually used - see encoding tests.)
742      */
743     streamInfo.pfnStreamOutput = NULL;
744     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
745      NULL, &streamInfo);
746     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
747     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
748     CryptMsgClose(msg);
749 }
750
751 static const BYTE emptyHashParam[] = {
752 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
753 0x7e };
754
755 static void test_hash_msg_get_param(void)
756 {
757     HCRYPTMSG msg;
758     BOOL ret;
759     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
760      { oid_rsa_md5, { 0, NULL } }, NULL };
761     DWORD size, value;
762     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
763     BYTE buf[16];
764
765     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
766      NULL, NULL);
767     /* Content and bare content are always gettable for non-streamed messages */
768     size = 0;
769     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
770     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
771     size = 0;
772     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
773     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
774     /* The hash is also available. */
775     size = 0;
776     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
777     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
778     ok(size == sizeof(buf), "Unexpected size %d\n", size);
779     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
780     if (size == sizeof(buf))
781         ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
782     /* By getting the hash, further updates are not allowed */
783     SetLastError(0xdeadbeef);
784     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
785     ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
786      "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
787     /* The version is also available, and should be zero for this message. */
788     size = 0;
789     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
790     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
791     size = sizeof(value);
792     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
793     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
794     ok(value == 0, "Expected version 0, got %d\n", value);
795     /* As usual, the type isn't available. */
796     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
797     ok(!ret, "Expected failure\n");
798     CryptMsgClose(msg);
799
800     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
801      NULL, &streamInfo);
802     /* Streamed messages don't allow you to get the content or bare content. */
803     SetLastError(0xdeadbeef);
804     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
805     ok(!ret && GetLastError() == E_INVALIDARG,
806      "Expected E_INVALIDARG, got %x\n", GetLastError());
807     SetLastError(0xdeadbeef);
808     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
809     ok(!ret && GetLastError() == E_INVALIDARG,
810      "Expected E_INVALIDARG, got %x\n", GetLastError());
811     /* The hash is still available. */
812     size = 0;
813     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
814     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
815     ok(size == sizeof(buf), "Unexpected size %d\n", size);
816     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
817     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
818     if (size == sizeof(buf))
819         ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
820     /* After updating the hash, further updates aren't allowed on streamed
821      * messages either.
822      */
823     SetLastError(0xdeadbeef);
824     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
825     ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
826      "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
827     CryptMsgClose(msg);
828 }
829
830 static const BYTE hashEmptyBareContent[] = {
831 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
832 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
833 static const BYTE hashEmptyContent[] = {
834 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
835 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
836 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
837 static const BYTE hashBareContent[] = {
838 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
839 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
840 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
841 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
842 static const BYTE hashContent[] = {
843 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
844 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
845 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
846 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
847 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
848
849 static const BYTE detachedHashNonFinalBareContent[] = {
850 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
851 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
852 0x07,0x01,0x04,0x00 };
853 static const BYTE detachedHashNonFinalContent[] = {
854 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
855 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
856 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
857 0x07,0x01,0x04,0x00 };
858 static const BYTE detachedHashBareContent[] = {
859 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
860 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
861 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
862 0x9d,0x2a,0x8f,0x26,0x2f };
863 static const BYTE detachedHashContent[] = {
864 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
865 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
866 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
867 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
868 0x9d,0x2a,0x8f,0x26,0x2f };
869
870 static void test_hash_msg_encoding(void)
871 {
872     HCRYPTMSG msg;
873     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
874     BOOL ret;
875     struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
876     CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
877
878     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
879     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
880      NULL, NULL);
881     check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
882      hashEmptyBareContent, sizeof(hashEmptyBareContent));
883     check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
884      hashEmptyContent, sizeof(hashEmptyContent));
885     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
886     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
887     check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
888      hashBareContent, sizeof(hashBareContent));
889     check_param("hash content", msg, CMSG_CONTENT_PARAM,
890      hashContent, sizeof(hashContent));
891     CryptMsgClose(msg);
892     /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
893     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
894      CMSG_HASHED, &hashInfo, NULL, NULL);
895     check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
896      hashEmptyBareContent, sizeof(hashEmptyBareContent));
897     check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
898      hashEmptyContent, sizeof(hashEmptyContent));
899     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
900     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
901     check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
902      hashBareContent, sizeof(hashBareContent));
903     check_param("hash content", msg, CMSG_CONTENT_PARAM,
904      hashContent, sizeof(hashContent));
905     CryptMsgClose(msg);
906     /* Same test, but with CMSG_DETACHED_FLAG set */
907     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
908      CMSG_HASHED, &hashInfo, NULL, NULL);
909     check_param("detached hash empty bare content", msg,
910      CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
911      sizeof(hashEmptyBareContent));
912     check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
913      hashEmptyContent, sizeof(hashEmptyContent));
914     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
915     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
916     check_param("detached hash not final bare content", msg,
917      CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
918      sizeof(detachedHashNonFinalBareContent));
919     check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
920      detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
921     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
922     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
923     check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
924      detachedHashBareContent, sizeof(detachedHashBareContent));
925     check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
926      detachedHashContent, sizeof(detachedHashContent));
927     check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
928      detachedHashBareContent, sizeof(detachedHashBareContent));
929     check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
930      detachedHashContent, sizeof(detachedHashContent));
931     CryptMsgClose(msg);
932     /* In what appears to be a bug, streamed updates to hash messages don't
933      * call the output function.
934      */
935     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
936      NULL, &streamInfo);
937     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
938     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
939     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
940     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
941     CryptMsgClose(msg);
942     check_updates("empty hash message", &empty_accum, &accum);
943     free_updates(&accum);
944
945     streamInfo.cbContent = sizeof(msgData);
946     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
947      NULL, &streamInfo);
948     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
949     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
950     CryptMsgClose(msg);
951     check_updates("hash message", &empty_accum, &accum);
952     free_updates(&accum);
953
954     streamInfo.cbContent = sizeof(msgData);
955     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
956      CMSG_HASHED, &hashInfo, NULL, &streamInfo);
957     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
958     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
959     CryptMsgClose(msg);
960     check_updates("detached hash message", &empty_accum, &accum);
961     free_updates(&accum);
962 }
963
964 static void test_hash_msg(void)
965 {
966     test_hash_msg_open();
967     test_hash_msg_update();
968     test_hash_msg_get_param();
969     test_hash_msg_encoding();
970 }
971
972 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
973  'm','p',0 };
974 static BYTE serialNum[] = { 1 };
975 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
976  0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
977
978 static void test_signed_msg_open(void)
979 {
980     HCRYPTMSG msg;
981     BOOL ret;
982     CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
983     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
984     CERT_INFO certInfo = { 0 };
985
986     SetLastError(0xdeadbeef);
987     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
988      NULL, NULL);
989     ok(!msg && GetLastError() == E_INVALIDARG,
990      "Expected E_INVALIDARG, got %x\n", GetLastError());
991     signInfo.cbSize = sizeof(signInfo);
992     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
993      NULL, NULL);
994     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
995     CryptMsgClose(msg);
996
997     signInfo.cSigners = 1;
998     signInfo.rgSigners = &signer;
999     /* With signer.pCertInfo unset, attempting to open this message this
1000      * crashes.
1001      */
1002     signer.pCertInfo = &certInfo;
1003     /* The cert info must contain a serial number and an issuer. */
1004     SetLastError(0xdeadbeef);
1005     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1006      NULL, NULL);
1007     ok(!msg && GetLastError() == E_INVALIDARG,
1008      "Expected E_INVALIDARG, got %x\n", GetLastError());
1009     certInfo.SerialNumber.cbData = sizeof(serialNum);
1010     certInfo.SerialNumber.pbData = serialNum;
1011     SetLastError(0xdeadbeef);
1012     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1013      NULL, NULL);
1014     ok(!msg && GetLastError() == E_INVALIDARG,
1015      "Expected E_INVALIDARG, got %x\n", GetLastError());
1016     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1017     certInfo.Issuer.pbData = encodedCommonName;
1018     SetLastError(0xdeadbeef);
1019     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1020      NULL, NULL);
1021     ok(!msg && GetLastError() == E_INVALIDARG,
1022      "Expected E_INVALIDARG, got %x\n", GetLastError());
1023
1024     /* The signer's hCryptProv must be set to something.  Whether it's usable
1025      * or not will be checked after the hash algorithm is checked (see next
1026      * test.)
1027      */
1028     signer.hCryptProv = 1;
1029     SetLastError(0xdeadbeef);
1030     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1031      NULL, NULL);
1032     ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1033      "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1034     /* The signer's hash algorithm must also be set. */
1035     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1036     SetLastError(0xdeadbeef);
1037     /* Crashes in advapi32 in wine, don't do it */
1038     if (0) {
1039         msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1040          &signInfo, NULL, NULL);
1041         ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1042          "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1043     }
1044     /* The signer's hCryptProv must also be valid. */
1045     ret = CryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1046      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1047     if (!ret && GetLastError() == NTE_EXISTS)
1048         ret = CryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1049          PROV_RSA_FULL, 0);
1050     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1051     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1052      NULL, NULL);
1053     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1054     CryptMsgClose(msg);
1055
1056     CryptReleaseContext(signer.hCryptProv, 0);
1057     CryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1058      PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1059 }
1060
1061 static const BYTE privKey[] = {
1062  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1063  0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1064  0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1065  0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1066  0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1067  0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1068  0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1069  0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1070  0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1071  0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1072  0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1073  0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1074  0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1075  0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1076  0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1077  0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1078  0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1079  0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1080  0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1081  0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1082  0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1083  0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1084  0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1085  0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1086
1087 static void test_signed_msg_update(void)
1088 {
1089     HCRYPTMSG msg;
1090     BOOL ret;
1091     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1092     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1093     CERT_INFO certInfo = { 0 };
1094     HCRYPTKEY key;
1095
1096     certInfo.SerialNumber.cbData = sizeof(serialNum);
1097     certInfo.SerialNumber.pbData = serialNum;
1098     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1099     certInfo.Issuer.pbData = encodedCommonName;
1100     signer.pCertInfo = &certInfo;
1101     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1102     signInfo.cSigners = 1;
1103     signInfo.rgSigners = &signer;
1104     ret = CryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1105      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1106     if (!ret && GetLastError() == NTE_EXISTS)
1107         ret = CryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1108          PROV_RSA_FULL, 0);
1109     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1110     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1111      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1112     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1113     /* Detached CMSG_SIGNED allows non-final updates. */
1114     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1115     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1116     /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1117     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1118     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1119     /* The final update requires a private key in the hCryptProv, in order to
1120      * generate the signature.
1121      */
1122     SetLastError(0xdeadbeef);
1123     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1124     ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1125      GetLastError() == NTE_NO_KEY),
1126      "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1127     ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1128      0, 0, &key);
1129     ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1130     /* The final update should be able to succeed now that a key exists, but
1131      * the previous (invalid) final update prevents it.
1132      */
1133     SetLastError(0xdeadbeef);
1134     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1135     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1136      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1137     CryptMsgClose(msg);
1138
1139     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1140      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1141     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1142     /* Detached CMSG_SIGNED allows non-final updates. */
1143     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1144     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1145     /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1146     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1147     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1148     /* Now that the private key exists, the final update can succeed (even
1149      * with no data.)
1150      */
1151     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1152     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1153     /* But no updates are allowed after the final update. */
1154     SetLastError(0xdeadbeef);
1155     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1156     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1157      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1158     SetLastError(0xdeadbeef);
1159     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1160     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1161      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1162     CryptMsgClose(msg);
1163
1164     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1165      NULL, NULL);
1166     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1167     /* Non-detached messages don't allow non-final updates.. */
1168     SetLastError(0xdeadbeef);
1169     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1170     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1171      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1172     /* but they do allow final ones. */
1173     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1174     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1175     CryptMsgClose(msg);
1176     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1177      NULL, NULL);
1178     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1179     /* They also allow final updates with no data. */
1180     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1181     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1182     CryptMsgClose(msg);
1183
1184     CryptDestroyKey(key);
1185     CryptReleaseContext(signer.hCryptProv, 0);
1186     CryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1187      CRYPT_DELETEKEYSET);
1188 }
1189
1190 static const BYTE signedEmptyBareContent[] = {
1191 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1192 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1193 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1194 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1195 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1196 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1197 static const BYTE signedEmptyContent[] = {
1198 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1199 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1200 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1201 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1202 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1203 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1204 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1205 static const BYTE detachedSignedBareContent[] = {
1206 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1207 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1208 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1209 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1210 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1211 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1212 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1213 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1214 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1215 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1216 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1217 static const BYTE detachedSignedContent[] = {
1218 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1219 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1220 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1221 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1222 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1223 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1224 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1225 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1226 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1227 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1228 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1229 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1230 static const BYTE signedBareContent[] = {
1231 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1232 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1233 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1234 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1235 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1236 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1237 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1238 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1239 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1240 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1241 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1242 static const BYTE signedContent[] = {
1243 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1244 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1245 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1246 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1247 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1248 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1249 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1250 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1251 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1252 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1253 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1254 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1255 0x0d };
1256 static const BYTE signedHash[] = {
1257 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1258 0x2f };
1259 static BYTE cert[] = {
1260 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1261 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1262 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1263 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1264 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1265 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1266 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1267 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1268 0xff,0x02,0x01,0x01 };
1269 static const BYTE signedWithCertEmptyBareContent[] = {
1270 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1271 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1272 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1273 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1274 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1275 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1276 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1277 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1278 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1279 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1280 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1281 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1282 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1283 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1284 static const BYTE signedWithCertBareContent[] = {
1285 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1286 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1287 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1288 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1289 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1290 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1291 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1292 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1293 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1294 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1295 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1296 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1297 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1298 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1299 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1300 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1301 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1302 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1303 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1304 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1305 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,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,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1308 0x30,0x30,0x30,0x30,0x5a };
1309 static const BYTE signedWithCrlEmptyBareContent[] = {
1310 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1311 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1312 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1313 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1314 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1315 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1316 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1317 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1318 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1319 static const BYTE signedWithCrlBareContent[] = {
1320 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1321 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1322 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1323 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1324 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1325 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1326 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1327 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1328 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1329 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1330 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1331 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1332 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1333 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1334 0xa8,0x0d };
1335 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1336 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1337 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1338 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1339 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1340 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1341 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1342 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1343 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1344 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1345 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1346 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1347 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1348 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1349 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1350 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1351 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1352 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1353 0x04,0x00 };
1354 static const BYTE signedWithCertAndCrlBareContent[] = {
1355 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1356 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1357 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1358 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1359 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1360 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1361 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1362 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1363 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1364 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1365 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1366 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1367 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1368 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1369 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1370 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1371 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1372 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1373 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1374 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1375 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1376 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1377 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1378
1379 static void test_signed_msg_encoding(void)
1380 {
1381     HCRYPTMSG msg;
1382     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1383     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1384     CERT_INFO certInfo = { 0 };
1385     CERT_BLOB encodedCert = { sizeof(cert), cert };
1386     CRL_BLOB encodedCrl = { sizeof(crl), crl };
1387     BOOL ret;
1388     HCRYPTKEY key;
1389     DWORD size;
1390
1391     certInfo.SerialNumber.cbData = sizeof(serialNum);
1392     certInfo.SerialNumber.pbData = serialNum;
1393     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1394     certInfo.Issuer.pbData = encodedCommonName;
1395     signer.pCertInfo = &certInfo;
1396     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1397     signInfo.cSigners = 1;
1398     signInfo.rgSigners = &signer;
1399     ret = CryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1400      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1401     if (!ret && GetLastError() == NTE_EXISTS)
1402         ret = CryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1403          PROV_RSA_FULL, 0);
1404     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1405     ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1406      0, 0, &key);
1407     ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1408
1409     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1410      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1411     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1412
1413     check_param("detached signed empty bare content", msg,
1414      CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1415      sizeof(signedEmptyBareContent));
1416     check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1417      signedEmptyContent, sizeof(signedEmptyContent));
1418     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1419     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1420     check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1421      signedHash, sizeof(signedHash));
1422     check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1423      detachedSignedBareContent, sizeof(detachedSignedBareContent));
1424     check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1425      detachedSignedContent, sizeof(detachedSignedContent));
1426     SetLastError(0xdeadbeef);
1427     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1428     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1429      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1430
1431     CryptMsgClose(msg);
1432
1433     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1434      NULL, NULL);
1435     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1436
1437     check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1438      signedEmptyBareContent, sizeof(signedEmptyBareContent));
1439     check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1440      signedEmptyContent, sizeof(signedEmptyContent));
1441     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1442     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1443     check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1444      signedBareContent, sizeof(signedBareContent));
1445     check_param("signed content", msg, CMSG_CONTENT_PARAM,
1446      signedContent, sizeof(signedContent));
1447
1448     CryptMsgClose(msg);
1449
1450     signInfo.rgCertEncoded = &encodedCert;
1451     signInfo.cCertEncoded = 1;
1452     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1453      NULL, NULL);
1454     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1455
1456     check_param("signed with cert empty bare content", msg,
1457      CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1458      sizeof(signedWithCertEmptyBareContent));
1459     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1460     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1461     check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1462      signedWithCertBareContent, sizeof(signedWithCertBareContent));
1463
1464     CryptMsgClose(msg);
1465
1466     signInfo.cCertEncoded = 0;
1467     signInfo.rgCrlEncoded = &encodedCrl;
1468     signInfo.cCrlEncoded = 1;
1469     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1470      NULL, NULL);
1471     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1472
1473     check_param("signed with crl empty bare content", msg,
1474      CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1475      sizeof(signedWithCrlEmptyBareContent));
1476     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1477     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1478     check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1479      signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1480
1481     CryptMsgClose(msg);
1482
1483     signInfo.cCertEncoded = 1;
1484     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1485      NULL, NULL);
1486     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1487
1488     check_param("signed with cert and crl empty bare content", msg,
1489      CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1490      sizeof(signedWithCertAndCrlEmptyBareContent));
1491     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1492     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1493     check_param("signed with cert and crl bare content", msg,
1494      CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1495      sizeof(signedWithCertAndCrlBareContent));
1496
1497     CryptMsgClose(msg);
1498
1499     CryptDestroyKey(key);
1500     CryptReleaseContext(signer.hCryptProv, 0);
1501     CryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1502      CRYPT_DELETEKEYSET);
1503 }
1504
1505 static void test_signed_msg_get_param(void)
1506 {
1507     BOOL ret;
1508     HCRYPTMSG msg;
1509     DWORD size, value = 0;
1510     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1511     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1512     CERT_INFO certInfo = { 0 };
1513
1514     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1515      NULL, NULL);
1516     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1517
1518     /* Content and bare content are always gettable */
1519     size = 0;
1520     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1521     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1522     size = 0;
1523     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1524     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1525     /* For "signed" messages, so is the version. */
1526     size = 0;
1527     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1528     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1529     size = sizeof(value);
1530     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1531     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1532     ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1533     /* But for this message, with no signers, the hash and signer aren't
1534      * available.
1535      */
1536     size = 0;
1537     SetLastError(0xdeadbeef);
1538     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1539     todo_wine
1540     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1541      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1542     SetLastError(0xdeadbeef);
1543     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1544     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1545      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1546     /* As usual, the type isn't available. */
1547     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1548     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1549      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1550
1551     CryptMsgClose(msg);
1552
1553     certInfo.SerialNumber.cbData = sizeof(serialNum);
1554     certInfo.SerialNumber.pbData = serialNum;
1555     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1556     certInfo.Issuer.pbData = encodedCommonName;
1557     signer.pCertInfo = &certInfo;
1558     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1559     signInfo.cSigners = 1;
1560     signInfo.rgSigners = &signer;
1561     ret = CryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1562      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1563     if (!ret && GetLastError() == NTE_EXISTS)
1564         ret = CryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1565          PROV_RSA_FULL, 0);
1566     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1567     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1568      NULL, NULL);
1569     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1570
1571     /* This message, with one signer, has the hash and signer for index 0
1572      * available, but not for other indexes.
1573      */
1574     size = 0;
1575     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1576     todo_wine
1577     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1578     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1579     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1580     size = 0;
1581     SetLastError(0xdeadbeef);
1582     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1583     todo_wine
1584     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1585      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
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     /* As usual, the type isn't available. */
1591     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1592     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1593      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1594
1595     CryptMsgClose(msg);
1596
1597     CryptReleaseContext(signer.hCryptProv, 0);
1598     CryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1599      PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1600 }
1601
1602 static void test_signed_msg(void)
1603 {
1604     test_signed_msg_open();
1605     test_signed_msg_update();
1606     test_signed_msg_encoding();
1607     test_signed_msg_get_param();
1608 }
1609
1610 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1611 static const struct update_accum a4 = { 1, &b4 };
1612
1613 static const BYTE bogusOIDContent[] = {
1614 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1615 0x04,0x00 };
1616 static const BYTE bogusHashContent[] = {
1617 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1618 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1619 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1620 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1621 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1622
1623 static void test_decode_msg_update(void)
1624 {
1625     HCRYPTMSG msg;
1626     BOOL ret;
1627     CMSG_STREAM_INFO streamInfo = { 0 };
1628     DWORD i;
1629     struct update_accum accum = { 0, NULL };
1630
1631     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1632     /* Update with a full message in a final update */
1633     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1634     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1635     /* Can't update after a final update */
1636     SetLastError(0xdeadbeef);
1637     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1638     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1639      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1640     CryptMsgClose(msg);
1641
1642     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1643     /* Can't send a non-final update without streaming */
1644     SetLastError(0xdeadbeef);
1645     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1646      FALSE);
1647     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1648      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1649     /* A subsequent final update succeeds */
1650     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1651     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1652     CryptMsgClose(msg);
1653
1654     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1655     /* Updating a message that has a NULL stream callback fails */
1656     SetLastError(0xdeadbeef);
1657     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1658      FALSE);
1659     todo_wine
1660     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1661      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1662     /* Changing the callback pointer after the fact yields the same error (so
1663      * the message must copy the stream info, not just store a pointer to it)
1664      */
1665     streamInfo.pfnStreamOutput = nop_stream_output;
1666     SetLastError(0xdeadbeef);
1667     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1668      FALSE);
1669     todo_wine
1670     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1671      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1672     CryptMsgClose(msg);
1673
1674     /* Empty non-final updates are allowed when streaming.. */
1675     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1676     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1677     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1678     /* but final updates aren't when not enough data has been received. */
1679     SetLastError(0xdeadbeef);
1680     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1681     todo_wine
1682     ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1683      "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1684     CryptMsgClose(msg);
1685
1686     /* Updating the message byte by byte is legal */
1687     streamInfo.pfnStreamOutput = accumulating_stream_output;
1688     streamInfo.pvArg = &accum;
1689     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1690     for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1691         ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1692     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1693     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1694     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1695     CryptMsgClose(msg);
1696     todo_wine
1697     check_updates("byte-by-byte empty content", &a4, &accum);
1698     free_updates(&accum);
1699
1700     /* Decoding bogus content fails in non-streaming mode.. */
1701     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1702     SetLastError(0xdeadbeef);
1703     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1704     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1705      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1706     CryptMsgClose(msg);
1707     /* and as the final update in streaming mode.. */
1708     streamInfo.pfnStreamOutput = nop_stream_output;
1709     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1710     SetLastError(0xdeadbeef);
1711     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1712     todo_wine
1713     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1714      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1715     CryptMsgClose(msg);
1716     /* and even as a non-final update in streaming mode. */
1717     streamInfo.pfnStreamOutput = nop_stream_output;
1718     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1719     SetLastError(0xdeadbeef);
1720     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1721     todo_wine
1722     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1723      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1724     CryptMsgClose(msg);
1725
1726     /* An empty message can be opened with indetermined type.. */
1727     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1728     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1729      TRUE);
1730     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1731     /* but decoding it as an explicitly typed message fails. */
1732     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1733      NULL);
1734     SetLastError(0xdeadbeef);
1735     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1736      TRUE);
1737     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1738      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1739     CryptMsgClose(msg);
1740     /* On the other hand, decoding the bare content of an empty message fails
1741      * with unspecified type..
1742      */
1743     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1744     SetLastError(0xdeadbeef);
1745     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1746      sizeof(dataEmptyBareContent), TRUE);
1747     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1748      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1749     CryptMsgClose(msg);
1750     /* but succeeds with explicit type. */
1751     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1752      NULL);
1753     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1754      sizeof(dataEmptyBareContent), TRUE);
1755     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1756     CryptMsgClose(msg);
1757
1758     /* Decoding valid content with an unsupported OID fails */
1759     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1760     SetLastError(0xdeadbeef);
1761     ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
1762     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1763      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1764     CryptMsgClose(msg);
1765
1766     /* Similarly, opening an empty hash with unspecified type succeeds.. */
1767     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1768     SetLastError(0xdeadbeef);
1769     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1770     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1771     CryptMsgClose(msg);
1772     /* while with specified type it fails. */
1773     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1774      NULL);
1775     SetLastError(0xdeadbeef);
1776     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1777     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1778      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1779     CryptMsgClose(msg);
1780     /* On the other hand, decoding the bare content of an empty hash message
1781      * fails with unspecified type..
1782      */
1783     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1784     SetLastError(0xdeadbeef);
1785     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1786      sizeof(hashEmptyBareContent), TRUE);
1787     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1788      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1789     CryptMsgClose(msg);
1790     /* but succeeds with explicit type. */
1791     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1792      NULL);
1793     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1794      sizeof(hashEmptyBareContent), TRUE);
1795     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1796     CryptMsgClose(msg);
1797
1798     /* And again, opening a (non-empty) hash message with unspecified type
1799      * succeeds..
1800      */
1801     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1802     SetLastError(0xdeadbeef);
1803     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
1804     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1805     CryptMsgClose(msg);
1806     /* while with specified type it fails.. */
1807     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1808      NULL);
1809     SetLastError(0xdeadbeef);
1810     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
1811     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1812      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1813     CryptMsgClose(msg);
1814     /* and decoding the bare content of a non-empty hash message fails with
1815      * unspecified type..
1816      */
1817     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1818     SetLastError(0xdeadbeef);
1819     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
1820     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1821      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1822     CryptMsgClose(msg);
1823     /* but succeeds with explicit type. */
1824     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1825      NULL);
1826     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
1827     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1828     CryptMsgClose(msg);
1829
1830     /* Opening a (non-empty) hash message with unspecified type and a bogus
1831      * hash value succeeds..
1832      */
1833     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1834     SetLastError(0xdeadbeef);
1835     ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
1836     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1837     CryptMsgClose(msg);
1838 }
1839
1840 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
1841  0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1842
1843 static void test_decode_msg_get_param(void)
1844 {
1845     HCRYPTMSG msg;
1846     BOOL ret;
1847     DWORD size = 0, version;
1848
1849     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1850     SetLastError(0xdeadbeef);
1851     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1852     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1853      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1854     ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
1855     check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
1856      sizeof(msgData));
1857     CryptMsgClose(msg);
1858
1859     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1860     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1861     check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
1862     check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
1863     check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1864      emptyHashParam, sizeof(emptyHashParam));
1865     CryptMsgClose(msg);
1866     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1867     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
1868     check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
1869      sizeof(msgData));
1870     check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
1871      sizeof(hashParam));
1872     check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1873      hashParam, sizeof(hashParam));
1874     size = strlen(szOID_RSA_data) + 1;
1875     check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
1876      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
1877     version = CMSG_HASHED_DATA_V0;
1878     check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&version,
1879      sizeof(version));
1880     CryptMsgClose(msg);
1881 }
1882
1883 static void test_decode_msg(void)
1884 {
1885     test_decode_msg_update();
1886     test_decode_msg_get_param();
1887 }
1888
1889 START_TEST(msg)
1890 {
1891     /* Basic parameter checking tests */
1892     test_msg_open_to_encode();
1893     test_msg_open_to_decode();
1894     test_msg_get_param();
1895     test_msg_close();
1896
1897     /* Message-type specific tests */
1898     test_data_msg();
1899     test_hash_msg();
1900     test_signed_msg();
1901     test_decode_msg();
1902 }