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