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