crypt32: Test an encoded signed message with a cert with a public key.
[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 BYTE v1CertWithPubKey[] = {
1315 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1316 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1317 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1318 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1319 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1320 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1321 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1322 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1323 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,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 };
1326 static const BYTE signedWithCertEmptyBareContent[] = {
1327 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1328 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1329 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1330 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1331 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1332 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1333 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1334 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1335 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1336 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1337 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1338 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1339 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1340 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1341 static const BYTE signedWithCertBareContent[] = {
1342 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1343 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1344 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1345 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1346 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1347 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1348 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1349 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1350 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1351 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1352 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1353 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1354 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1355 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1356 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1357 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1358 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1359 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1360 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1361 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1362 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1363 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1364 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1365 0x30,0x30,0x30,0x30,0x5a };
1366 static const BYTE signedWithCrlEmptyBareContent[] = {
1367 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1368 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1369 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1370 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1371 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1372 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1373 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1374 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1375 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1376 static const BYTE signedWithCrlBareContent[] = {
1377 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1378 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1379 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1380 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1381 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1382 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1383 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1384 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1385 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1386 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1387 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1388 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1389 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1390 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1391 0xa8,0x0d };
1392 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1393 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1394 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1395 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1396 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1397 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1398 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1399 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1400 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1401 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1402 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1403 0x01,0x01,0xa1,0x2e,0x30,0x2c,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,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1406 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1407 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1408 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1409 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1410 0x04,0x00 };
1411 static const BYTE signedWithCertAndCrlBareContent[] = {
1412 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1413 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1414 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1415 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1416 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1417 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1418 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1419 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1420 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1421 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1422 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1423 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1424 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1425 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1426 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1427 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1428 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1429 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1430 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1431 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1432 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1433 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1434 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1435 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1436 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1437 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1438 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1439 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1440 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1441 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1442 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1443 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1444 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1445 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1446 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1447 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1448 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1449 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1450 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1451 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1452
1453 static void test_signed_msg_encoding(void)
1454 {
1455     HCRYPTMSG msg;
1456     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1457     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1458     CERT_INFO certInfo = { 0 };
1459     CERT_BLOB encodedCert = { sizeof(cert), cert };
1460     CRL_BLOB encodedCrl = { sizeof(crl), crl };
1461     char oid_common_name[] = szOID_COMMON_NAME;
1462     CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1463      encodedCommonName };
1464     CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1465     BOOL ret;
1466     HCRYPTKEY key;
1467     DWORD size;
1468
1469     certInfo.SerialNumber.cbData = sizeof(serialNum);
1470     certInfo.SerialNumber.pbData = serialNum;
1471     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1472     certInfo.Issuer.pbData = encodedCommonName;
1473     signer.pCertInfo = &certInfo;
1474     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1475     signInfo.cSigners = 1;
1476     signInfo.rgSigners = &signer;
1477     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1478      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1479     if (!ret && GetLastError() == NTE_EXISTS)
1480         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1481          PROV_RSA_FULL, 0);
1482     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1483     ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1484      0, 0, &key);
1485     ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1486
1487     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1488      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1489     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1490
1491     check_param("detached signed empty bare content", msg,
1492      CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1493      sizeof(signedEmptyBareContent));
1494     check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1495      signedEmptyContent, sizeof(signedEmptyContent));
1496     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1497     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1498     check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1499      signedHash, sizeof(signedHash));
1500     check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1501      detachedSignedBareContent, sizeof(detachedSignedBareContent));
1502     check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1503      detachedSignedContent, sizeof(detachedSignedContent));
1504     SetLastError(0xdeadbeef);
1505     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1506     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1507      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1508     check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1509      signedEncodedSigner, sizeof(signedEncodedSigner));
1510
1511     CryptMsgClose(msg);
1512
1513     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1514      NULL, NULL);
1515     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1516
1517     check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1518      signedEmptyBareContent, sizeof(signedEmptyBareContent));
1519     check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1520      signedEmptyContent, sizeof(signedEmptyContent));
1521     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1522     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1523     check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1524      signedBareContent, sizeof(signedBareContent));
1525     check_param("signed content", msg, CMSG_CONTENT_PARAM,
1526      signedContent, sizeof(signedContent));
1527
1528     CryptMsgClose(msg);
1529
1530     signer.cAuthAttr = 1;
1531     signer.rgAuthAttr = &attr;
1532     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1533      NULL, NULL);
1534     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1535
1536     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1537     check_param("signed with auth attrs bare content", msg,
1538      CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1539      sizeof(signedWithAuthAttrsBareContent));
1540
1541     CryptMsgClose(msg);
1542
1543     signer.cAuthAttr = 0;
1544     signInfo.rgCertEncoded = &encodedCert;
1545     signInfo.cCertEncoded = 1;
1546     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1547      NULL, NULL);
1548     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1549
1550     check_param("signed with cert empty bare content", msg,
1551      CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1552      sizeof(signedWithCertEmptyBareContent));
1553     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1554     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1555     check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1556      signedWithCertBareContent, sizeof(signedWithCertBareContent));
1557
1558     CryptMsgClose(msg);
1559
1560     signInfo.cCertEncoded = 0;
1561     signInfo.rgCrlEncoded = &encodedCrl;
1562     signInfo.cCrlEncoded = 1;
1563     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1564      NULL, NULL);
1565     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1566
1567     check_param("signed with crl empty bare content", msg,
1568      CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1569      sizeof(signedWithCrlEmptyBareContent));
1570     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1571     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1572     check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1573      signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1574
1575     CryptMsgClose(msg);
1576
1577     signInfo.cCertEncoded = 1;
1578     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1579      NULL, NULL);
1580     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1581
1582     check_param("signed with cert and crl empty bare content", msg,
1583      CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1584      sizeof(signedWithCertAndCrlEmptyBareContent));
1585     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1586     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1587     check_param("signed with cert and crl bare content", msg,
1588      CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1589      sizeof(signedWithCertAndCrlBareContent));
1590
1591     CryptMsgClose(msg);
1592
1593     /* Test with a cert with a (bogus) public key */
1594     signInfo.cCrlEncoded = 0;
1595     encodedCert.cbData = sizeof(v1CertWithPubKey);
1596     encodedCert.pbData = v1CertWithPubKey;
1597     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1598      NULL, NULL);
1599     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1600     check_param("signedWithCertWithPubKeyBareContent", msg,
1601      CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1602      sizeof(signedWithCertWithPubKeyBareContent));
1603     CryptMsgClose(msg);
1604
1605     CryptDestroyKey(key);
1606     CryptReleaseContext(signer.hCryptProv, 0);
1607     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1608      CRYPT_DELETEKEYSET);
1609 }
1610
1611 static void test_signed_msg_get_param(void)
1612 {
1613     BOOL ret;
1614     HCRYPTMSG msg;
1615     DWORD size, value = 0;
1616     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1617     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1618     CERT_INFO certInfo = { 0 };
1619
1620     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1621      NULL, NULL);
1622     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1623
1624     /* Content and bare content are always gettable */
1625     size = 0;
1626     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1627     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1628     size = 0;
1629     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1630     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1631     /* For "signed" messages, so is the version. */
1632     size = 0;
1633     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1634     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1635     size = sizeof(value);
1636     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1637     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1638     ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1639     /* But for this message, with no signers, the hash and signer aren't
1640      * available.
1641      */
1642     size = 0;
1643     SetLastError(0xdeadbeef);
1644     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1645     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1646      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1647     SetLastError(0xdeadbeef);
1648     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1649     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1650      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1651     /* As usual, the type isn't available. */
1652     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1653     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1654      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1655
1656     CryptMsgClose(msg);
1657
1658     certInfo.SerialNumber.cbData = sizeof(serialNum);
1659     certInfo.SerialNumber.pbData = serialNum;
1660     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1661     certInfo.Issuer.pbData = encodedCommonName;
1662     signer.pCertInfo = &certInfo;
1663     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1664     signInfo.cSigners = 1;
1665     signInfo.rgSigners = &signer;
1666     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1667      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1668     if (!ret && GetLastError() == NTE_EXISTS)
1669         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1670          PROV_RSA_FULL, 0);
1671     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1672     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1673      NULL, NULL);
1674     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1675
1676     /* This message, with one signer, has the hash and signer for index 0
1677      * available, but not for other indexes.
1678      */
1679     size = 0;
1680     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1681     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1682     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1683     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1684     size = 0;
1685     SetLastError(0xdeadbeef);
1686     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1687     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1688      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1689     SetLastError(0xdeadbeef);
1690     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1691     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1692      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1693     /* As usual, the type isn't available. */
1694     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1695     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1696      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1697
1698     CryptMsgClose(msg);
1699
1700     CryptReleaseContext(signer.hCryptProv, 0);
1701     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1702      PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1703 }
1704
1705 static void test_signed_msg(void)
1706 {
1707     test_signed_msg_open();
1708     test_signed_msg_update();
1709     test_signed_msg_encoding();
1710     test_signed_msg_get_param();
1711 }
1712
1713 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1714 static const struct update_accum a4 = { 1, &b4 };
1715
1716 static const BYTE bogusOIDContent[] = {
1717 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1718 0x04,0x00 };
1719 static const BYTE bogusHashContent[] = {
1720 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1721 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1722 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1723 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1724 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1725
1726 static void test_decode_msg_update(void)
1727 {
1728     HCRYPTMSG msg;
1729     BOOL ret;
1730     CMSG_STREAM_INFO streamInfo = { 0 };
1731     DWORD i;
1732     struct update_accum accum = { 0, NULL };
1733
1734     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1735     /* Update with a full message in a final update */
1736     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1737     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1738     /* Can't update after a final update */
1739     SetLastError(0xdeadbeef);
1740     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1741     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1742      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1743     CryptMsgClose(msg);
1744
1745     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1746     /* Can't send a non-final update without streaming */
1747     SetLastError(0xdeadbeef);
1748     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1749      FALSE);
1750     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1751      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1752     /* A subsequent final update succeeds */
1753     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1754     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1755     CryptMsgClose(msg);
1756
1757     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1758     /* Updating a message that has a NULL stream callback fails */
1759     SetLastError(0xdeadbeef);
1760     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1761      FALSE);
1762     todo_wine
1763     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1764      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1765     /* Changing the callback pointer after the fact yields the same error (so
1766      * the message must copy the stream info, not just store a pointer to it)
1767      */
1768     streamInfo.pfnStreamOutput = nop_stream_output;
1769     SetLastError(0xdeadbeef);
1770     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1771      FALSE);
1772     todo_wine
1773     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1774      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1775     CryptMsgClose(msg);
1776
1777     /* Empty non-final updates are allowed when streaming.. */
1778     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1779     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1780     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1781     /* but final updates aren't when not enough data has been received. */
1782     SetLastError(0xdeadbeef);
1783     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1784     todo_wine
1785     ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1786      "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1787     CryptMsgClose(msg);
1788
1789     /* Updating the message byte by byte is legal */
1790     streamInfo.pfnStreamOutput = accumulating_stream_output;
1791     streamInfo.pvArg = &accum;
1792     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1793     for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1794         ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1795     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1796     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1797     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1798     CryptMsgClose(msg);
1799     todo_wine
1800     check_updates("byte-by-byte empty content", &a4, &accum);
1801     free_updates(&accum);
1802
1803     /* Decoding bogus content fails in non-streaming mode.. */
1804     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1805     SetLastError(0xdeadbeef);
1806     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1807     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1808      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1809     CryptMsgClose(msg);
1810     /* and as the final update in streaming mode.. */
1811     streamInfo.pfnStreamOutput = nop_stream_output;
1812     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1813     SetLastError(0xdeadbeef);
1814     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1815     todo_wine
1816     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1817      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1818     CryptMsgClose(msg);
1819     /* and even as a non-final update in streaming mode. */
1820     streamInfo.pfnStreamOutput = nop_stream_output;
1821     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1822     SetLastError(0xdeadbeef);
1823     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1824     todo_wine
1825     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1826      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1827     CryptMsgClose(msg);
1828
1829     /* An empty message can be opened with indetermined type.. */
1830     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1831     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1832      TRUE);
1833     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1834     /* but decoding it as an explicitly typed message fails. */
1835     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1836      NULL);
1837     SetLastError(0xdeadbeef);
1838     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1839      TRUE);
1840     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1841      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1842     CryptMsgClose(msg);
1843     /* On the other hand, decoding the bare content of an empty message fails
1844      * with unspecified type..
1845      */
1846     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1847     SetLastError(0xdeadbeef);
1848     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1849      sizeof(dataEmptyBareContent), TRUE);
1850     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1851      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1852     CryptMsgClose(msg);
1853     /* but succeeds with explicit type. */
1854     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1855      NULL);
1856     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1857      sizeof(dataEmptyBareContent), TRUE);
1858     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1859     CryptMsgClose(msg);
1860
1861     /* Decoding valid content with an unsupported OID fails */
1862     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1863     SetLastError(0xdeadbeef);
1864     ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
1865     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1866      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1867     CryptMsgClose(msg);
1868
1869     /* Similarly, opening an empty hash with unspecified type succeeds.. */
1870     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1871     SetLastError(0xdeadbeef);
1872     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1873     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1874     CryptMsgClose(msg);
1875     /* while with specified type it fails. */
1876     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1877      NULL);
1878     SetLastError(0xdeadbeef);
1879     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1880     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1881      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1882     CryptMsgClose(msg);
1883     /* On the other hand, decoding the bare content of an empty hash message
1884      * fails with unspecified type..
1885      */
1886     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1887     SetLastError(0xdeadbeef);
1888     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1889      sizeof(hashEmptyBareContent), TRUE);
1890     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1891      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1892     CryptMsgClose(msg);
1893     /* but succeeds with explicit type. */
1894     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1895      NULL);
1896     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1897      sizeof(hashEmptyBareContent), TRUE);
1898     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1899     CryptMsgClose(msg);
1900
1901     /* And again, opening a (non-empty) hash message with unspecified type
1902      * succeeds..
1903      */
1904     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1905     SetLastError(0xdeadbeef);
1906     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
1907     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1908     CryptMsgClose(msg);
1909     /* while with specified type it fails.. */
1910     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1911      NULL);
1912     SetLastError(0xdeadbeef);
1913     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
1914     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1915      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1916     CryptMsgClose(msg);
1917     /* and decoding the bare content of a non-empty hash message fails with
1918      * unspecified type..
1919      */
1920     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1921     SetLastError(0xdeadbeef);
1922     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
1923     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1924      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1925     CryptMsgClose(msg);
1926     /* but succeeds with explicit type. */
1927     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1928      NULL);
1929     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
1930     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1931     CryptMsgClose(msg);
1932
1933     /* Opening a (non-empty) hash message with unspecified type and a bogus
1934      * hash value succeeds..
1935      */
1936     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1937     SetLastError(0xdeadbeef);
1938     ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
1939     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1940     CryptMsgClose(msg);
1941
1942     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1943     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
1944     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1945     CryptMsgClose(msg);
1946     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1947     SetLastError(0xdeadbeef);
1948     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
1949      sizeof(signedWithCertAndCrlBareContent), TRUE);
1950     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1951      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1952     CryptMsgClose(msg);
1953     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
1954      NULL);
1955     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
1956      sizeof(signedWithCertAndCrlBareContent), TRUE);
1957     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1958     CryptMsgClose(msg);
1959 }
1960
1961 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
1962  0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1963
1964 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
1965  const CMSG_SIGNER_INFO *expected)
1966 {
1967     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
1968      expected->dwVersion, got->dwVersion);
1969     ok(got->Issuer.cbData == expected->Issuer.cbData,
1970      "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
1971      got->Issuer.cbData);
1972     ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
1973      "Unexpected issuer\n");
1974     ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
1975      "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
1976      got->SerialNumber.cbData);
1977     ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
1978      got->SerialNumber.cbData), "Unexpected serial number\n");
1979     /* FIXME: check more things */
1980 }
1981
1982 static void test_decode_msg_get_param(void)
1983 {
1984     HCRYPTMSG msg;
1985     BOOL ret;
1986     DWORD size = 0, value;
1987     LPBYTE buf;
1988
1989     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1990     SetLastError(0xdeadbeef);
1991     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1992     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1993      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1994     ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
1995     check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
1996      sizeof(msgData));
1997     CryptMsgClose(msg);
1998
1999     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2000     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2001     check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2002     check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2003     check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2004      emptyHashParam, sizeof(emptyHashParam));
2005     CryptMsgClose(msg);
2006     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2007     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2008     check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2009      sizeof(msgData));
2010     check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2011      sizeof(hashParam));
2012     check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2013      hashParam, sizeof(hashParam));
2014     /* Curiously, getting the hash of index 1 succeeds, even though there's
2015      * only one hash.
2016      */
2017     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2018     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2019     buf = CryptMemAlloc(size);
2020     if (buf)
2021     {
2022         ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2023         ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2024         ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2025         CryptMemFree(buf);
2026     }
2027     check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2028      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2029     value = CMSG_HASHED_DATA_V0;
2030     check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2031      sizeof(value));
2032     CryptMsgClose(msg);
2033
2034     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2035     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2036     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2037     check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2038      sizeof(msgData));
2039     check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2040      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2041     size = sizeof(value);
2042     value = 2112;
2043     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2044     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2045     ok(value == 1, "Expected 1 signer, got %d\n", value);
2046     size = 0;
2047     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2048     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2049     if (ret)
2050         buf = CryptMemAlloc(size);
2051     else
2052         buf = NULL;
2053     if (buf)
2054     {
2055         CMSG_SIGNER_INFO signer = { 0 };
2056
2057         signer.dwVersion = 1;
2058         signer.Issuer.cbData = sizeof(encodedCommonName);
2059         signer.Issuer.pbData = encodedCommonName;
2060         signer.SerialNumber.cbData = sizeof(serialNum);
2061         signer.SerialNumber.pbData = serialNum;
2062         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2063         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2064         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2065         CryptMemFree(buf);
2066     }
2067     /* index is ignored when getting signer count */
2068     size = sizeof(value);
2069     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2070     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2071     ok(value == 1, "Expected 1 signer, got %d\n", value);
2072     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2073     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2074     ok(value == 0, "Expected 0 certs, got %d\n", value);
2075     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2076     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2077     ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2078     CryptMsgClose(msg);
2079     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2080      NULL);
2081     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2082      sizeof(signedWithCertAndCrlBareContent), TRUE);
2083     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2084     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2085     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2086     ok(value == 1, "Expected 1 cert, got %d\n", value);
2087     check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2088     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2089     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2090     ok(value == 1, "Expected 1 CRL, got %d\n", value);
2091     check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2092     CryptMsgClose(msg);
2093 }
2094
2095 static void test_decode_msg(void)
2096 {
2097     test_decode_msg_update();
2098     test_decode_msg_get_param();
2099 }
2100
2101 START_TEST(msg)
2102 {
2103      init_function_pointers();
2104
2105     /* Basic parameter checking tests */
2106     test_msg_open_to_encode();
2107     test_msg_open_to_decode();
2108     test_msg_get_param();
2109     test_msg_close();
2110
2111     /* Message-type specific tests */
2112     test_data_msg();
2113     test_hash_msg();
2114     test_signed_msg();
2115     test_decode_msg();
2116 }