wintrust: Use helper function for setting confidence in SoftpubCheckCert.
[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 #define CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS
27 #define CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS
28 #include <wincrypt.h>
29
30 #include "wine/test.h"
31
32 static BOOL have_nt;
33 static char oid_rsa_md5[] = szOID_RSA_MD5;
34
35 static BOOL (WINAPI * pCryptAcquireContextA)
36                         (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
37 static BOOL (WINAPI * pCryptAcquireContextW)
38                         (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
39
40 static void init_function_pointers(void)
41 {
42     HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
43
44 #define GET_PROC(dll, func) \
45     p ## func = (void *)GetProcAddress(dll, #func); \
46     if(!p ## func) \
47       trace("GetProcAddress(%s) failed\n", #func);
48
49     GET_PROC(hAdvapi32, CryptAcquireContextA)
50     GET_PROC(hAdvapi32, CryptAcquireContextW)
51
52 #undef GET_PROC
53 }
54
55 static void test_msg_open_to_encode(void)
56 {
57     HCRYPTMSG msg;
58
59     /* Crash
60     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
61      NULL, NULL);
62     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
63      NULL);
64     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
65      NULL);
66      */
67
68     /* Bad encodings */
69     SetLastError(0xdeadbeef);
70     msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
71     ok(!msg && GetLastError() == E_INVALIDARG,
72      "Expected E_INVALIDARG, got %x\n", GetLastError());
73     SetLastError(0xdeadbeef);
74     msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
75     ok(!msg && GetLastError() == E_INVALIDARG,
76      "Expected E_INVALIDARG, got %x\n", GetLastError());
77
78     /* Bad message types */
79     SetLastError(0xdeadbeef);
80     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
81     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
82      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
83     SetLastError(0xdeadbeef);
84     msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
85      NULL, NULL, NULL);
86     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
87      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
88     SetLastError(0xdeadbeef);
89     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
90      CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
91     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
92      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
93     SetLastError(0xdeadbeef);
94     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
95      NULL, NULL);
96     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
97      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
98 }
99
100 static void test_msg_open_to_decode(void)
101 {
102     HCRYPTMSG msg;
103     CMSG_STREAM_INFO streamInfo = { 0 };
104
105     SetLastError(0xdeadbeef);
106     msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
107     ok(!msg && GetLastError() == E_INVALIDARG,
108      "Expected E_INVALIDARG, got %x\n", GetLastError());
109
110     /* Bad encodings */
111     SetLastError(0xdeadbeef);
112     msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
113     ok(!msg && GetLastError() == E_INVALIDARG,
114      "Expected E_INVALIDARG, got %x\n", GetLastError());
115     SetLastError(0xdeadbeef);
116     msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
117     ok(!msg && GetLastError() == E_INVALIDARG,
118      "Expected E_INVALIDARG, got %x\n", GetLastError());
119
120     /* The message type can be explicit... */
121     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
122      NULL);
123     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
124     CryptMsgClose(msg);
125     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
126      NULL);
127     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
128     CryptMsgClose(msg);
129     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
130      NULL);
131     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
132     CryptMsgClose(msg);
133     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
134      NULL);
135     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
136     CryptMsgClose(msg);
137     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
138      CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
139     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
140     CryptMsgClose(msg);
141     /* or implicit.. */
142     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
143     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
144     CryptMsgClose(msg);
145     /* or even invalid. */
146     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
147      NULL);
148     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
149     CryptMsgClose(msg);
150     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
151     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
152     CryptMsgClose(msg);
153
154     /* And even though the stream info parameter "must be set to NULL" for
155      * CMSG_HASHED, it's still accepted.
156      */
157     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
158      &streamInfo);
159     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
160     CryptMsgClose(msg);
161 }
162
163 static void test_msg_get_param(void)
164 {
165     BOOL ret;
166     HCRYPTMSG msg;
167     DWORD size, i, value;
168     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
169     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
170
171     /* Crash
172     ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
173     ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
174     ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
175      */
176
177     /* Decoded messages */
178     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
179     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
180     /* For decoded messages, the type is always available */
181     size = 0;
182     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
183     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
184     size = sizeof(value);
185     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
186     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
187     /* For this (empty) message, the type isn't set */
188     ok(value == 0, "Expected type 0, got %d\n", value);
189     CryptMsgClose(msg);
190
191     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
192      NULL);
193     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
194     /* For explicitly typed messages, the type is known. */
195     size = sizeof(value);
196     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
197     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
198     ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
199     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
200     {
201         size = 0;
202         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
203         ok(!ret, "Parameter %d: expected failure\n", i);
204     }
205     CryptMsgClose(msg);
206
207     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
208      NULL);
209     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
210     size = sizeof(value);
211     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
212     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
213     ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
214     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
215     {
216         size = 0;
217         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
218         ok(!ret, "Parameter %d: expected failure\n", i);
219     }
220     CryptMsgClose(msg);
221
222     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
223      NULL);
224     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
225     size = sizeof(value);
226     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
227     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
228     ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
229     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
230     {
231         size = 0;
232         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
233         ok(!ret, "Parameter %d: expected failure\n", i);
234     }
235     CryptMsgClose(msg);
236
237     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
238      NULL);
239     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
240     size = sizeof(value);
241     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
242     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
243     ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
244     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
245     {
246         size = 0;
247         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
248         ok(!ret, "Parameter %d: expected failure\n", i);
249     }
250     CryptMsgClose(msg);
251
252     /* Explicitly typed messages get their types set, even if they're invalid */
253     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
254      NULL);
255     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
256     size = sizeof(value);
257     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
258     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
259     ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
260     CryptMsgClose(msg);
261
262     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
263     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
264     size = sizeof(value);
265     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
266     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
267     ok(value == 1000, "Expected 1000, got %d\n", value);
268     CryptMsgClose(msg);
269 }
270
271 static void test_msg_close(void)
272 {
273     BOOL ret;
274     HCRYPTMSG msg;
275
276     /* NULL succeeds.. */
277     ret = CryptMsgClose(NULL);
278     ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
279     /* but an arbitrary pointer crashes. */
280     if (0)
281         ret = CryptMsgClose((HCRYPTMSG)1);
282     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
283      NULL);
284     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
285     ret = CryptMsgClose(msg);
286     ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
287 }
288
289 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
290  const BYTE *expected, DWORD expectedSize)
291 {
292     DWORD size;
293     LPBYTE buf;
294     BOOL ret;
295
296     size = 0xdeadbeef;
297     ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
298     ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
299     buf = HeapAlloc(GetProcessHeap(), 0, size);
300     ret = CryptMsgGetParam(msg, param, 0, buf, &size);
301     ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
302     ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
303      expectedSize, size);
304     if (size == expectedSize && size)
305         ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
306     HeapFree(GetProcessHeap(), 0, buf);
307 }
308
309 static void test_data_msg_open(void)
310 {
311     HCRYPTMSG msg;
312     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
313     CMSG_STREAM_INFO streamInfo = { 0 };
314     char oid[] = "1.2.3";
315
316     /* The data message type takes no additional info */
317     SetLastError(0xdeadbeef);
318     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
319      NULL, NULL);
320     ok(!msg && GetLastError() == E_INVALIDARG,
321      "Expected E_INVALIDARG, got %x\n", GetLastError());
322     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
323      NULL);
324     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
325     CryptMsgClose(msg);
326
327     /* An empty stream info is allowed. */
328     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
329      &streamInfo);
330     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
331     CryptMsgClose(msg);
332
333     /* Passing a bogus inner OID succeeds for a non-streamed message.. */
334     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
335      NULL);
336     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
337     CryptMsgClose(msg);
338     /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
339     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
340      CMSG_DATA, NULL, oid, NULL);
341     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
342     CryptMsgClose(msg);
343     /* and when a stream info is given, even though you're not supposed to be
344      * able to use anything but szOID_RSA_data when streaming is being used.
345      */
346     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
347      CMSG_DATA, NULL, oid, &streamInfo);
348     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
349     CryptMsgClose(msg);
350 }
351
352 static const BYTE msgData[] = { 1, 2, 3, 4 };
353
354 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
355  BOOL final)
356 {
357     return TRUE;
358 }
359
360 static void test_data_msg_update(void)
361 {
362     HCRYPTMSG msg;
363     BOOL ret;
364     CMSG_STREAM_INFO streamInfo = { 0 };
365
366     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
367      NULL);
368     /* Can't update a message that wasn't opened detached with final = FALSE */
369     SetLastError(0xdeadbeef);
370     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
371     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
372      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
373     /* Updating it with final = TRUE succeeds */
374     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
375     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
376     /* Any subsequent update will fail, as the last was final */
377     SetLastError(0xdeadbeef);
378     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
379     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
380      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
381     CryptMsgClose(msg);
382
383     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
384      NULL);
385     /* Can't update a message with no data */
386     SetLastError(0xdeadbeef);
387     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
388     /* This test returns FALSE on XP and earlier but TRUE on Vista, so can't be tested.
389      * GetLastError is either E_INVALIDARG (NT) or unset (9x/Vista), so it doesn't
390      * make sense to test this.
391      */
392
393     /* Curiously, a valid update will now fail as well, presumably because of
394      * the last (invalid, but final) update.
395      */
396     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
397     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
398      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
399     CryptMsgClose(msg);
400
401     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
402      CMSG_DATA, NULL, NULL, NULL);
403     /* Doesn't appear to be able to update CMSG-DATA with non-final updates */
404     SetLastError(0xdeadbeef);
405     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
406     ok(!ret && GetLastError() == E_INVALIDARG,
407      "Expected E_INVALIDARG, got %x\n", GetLastError());
408     SetLastError(0xdeadbeef);
409     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
410     ok(!ret && GetLastError() == E_INVALIDARG,
411      "Expected E_INVALIDARG, got %x\n", GetLastError());
412     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
413     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
414     CryptMsgClose(msg);
415
416     /* Calling update after opening with an empty stream info (with a bogus
417      * output function) yields an error:
418      */
419     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
420      &streamInfo);
421     SetLastError(0xdeadbeef);
422     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
423     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
424      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
425     CryptMsgClose(msg);
426     /* Calling update with a valid output function succeeds, even if the data
427      * exceeds the size specified in the stream info.
428      */
429     streamInfo.pfnStreamOutput = nop_stream_output;
430     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
431      &streamInfo);
432     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
433     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
434     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
435     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
436     CryptMsgClose(msg);
437 }
438
439 static void test_data_msg_get_param(void)
440 {
441     HCRYPTMSG msg;
442     DWORD size;
443     BOOL ret;
444     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
445
446     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
447      NULL);
448
449     /* Content and bare content are always gettable when not streaming */
450     size = 0;
451     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
452     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
453     size = 0;
454     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
455     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
456     /* But for this type of message, the signer and hash aren't applicable,
457      * and the type isn't available.
458      */
459     size = 0;
460     SetLastError(0xdeadbeef);
461     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
462     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
463      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
464     SetLastError(0xdeadbeef);
465     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
466     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
467      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
468     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
469     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
470      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
471     CryptMsgClose(msg);
472
473     /* Can't get content or bare content when streaming */
474     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
475      NULL, &streamInfo);
476     SetLastError(0xdeadbeef);
477     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
478     ok(!ret && GetLastError() == E_INVALIDARG,
479      "Expected E_INVALIDARG, got %x\n", GetLastError());
480     SetLastError(0xdeadbeef);
481     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
482     ok(!ret && GetLastError() == E_INVALIDARG,
483      "Expected E_INVALIDARG, got %x\n", GetLastError());
484     CryptMsgClose(msg);
485 }
486
487 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
488 static const BYTE dataEmptyContent[] = {
489 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
490 0x04,0x00 };
491 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
492 static const BYTE dataContent[] = {
493 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
494 0x04,0x04,0x01,0x02,0x03,0x04 };
495
496 struct update_accum
497 {
498     DWORD cUpdates;
499     CRYPT_DATA_BLOB *updates;
500 };
501
502 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
503  DWORD cb, BOOL final)
504 {
505     struct update_accum *accum = (struct update_accum *)pvArg;
506     BOOL ret = FALSE;
507
508     if (accum->cUpdates)
509         accum->updates = CryptMemRealloc(accum->updates,
510          (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
511     else
512         accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
513     if (accum->updates)
514     {
515         CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
516
517         blob->pbData = CryptMemAlloc(cb);
518         if (blob->pbData)
519         {
520             memcpy(blob->pbData, pb, cb);
521             blob->cbData = cb;
522             ret = TRUE;
523         }
524         accum->cUpdates++;
525     }
526     return ret;
527 }
528
529 /* The updates of a (bogus) definite-length encoded message */
530 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
531  0x07,0x01,0xa0,0x02,0x04,0x00 };
532 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
533 static CRYPT_DATA_BLOB b1[] = {
534     { sizeof(u1), u1 },
535     { sizeof(u2), u2 },
536     { sizeof(u2), u2 },
537 };
538 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
539 /* The updates of a definite-length encoded message */
540 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
541  0x07,0x01,0xa0,0x06,0x04,0x04 };
542 static CRYPT_DATA_BLOB b2[] = {
543     { sizeof(u3), u3 },
544     { sizeof(u2), u2 },
545 };
546 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
547 /* The updates of an indefinite-length encoded message */
548 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
549  0x07,0x01,0xa0,0x80,0x24,0x80 };
550 static BYTE u5[] = { 0x04,0x04 };
551 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
552 static CRYPT_DATA_BLOB b3[] = {
553     { sizeof(u4), u4 },
554     { sizeof(u5), u5 },
555     { sizeof(u2), u2 },
556     { sizeof(u5), u5 },
557     { sizeof(u2), u2 },
558     { sizeof(u6), u6 },
559 };
560 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
561
562 static void check_updates(LPCSTR header, const struct update_accum *expected,
563  const struct update_accum *got)
564 {
565     DWORD i;
566
567     ok(expected->cUpdates == got->cUpdates,
568      "%s: expected %d updates, got %d\n", header, expected->cUpdates,
569      got->cUpdates);
570     if (expected->cUpdates == got->cUpdates)
571         for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
572         {
573             ok(expected->updates[i].cbData == got->updates[i].cbData,
574              "%s, update %d: expected %d bytes, got %d\n", header, i,
575              expected->updates[i].cbData, got->updates[i].cbData);
576             if (expected->updates[i].cbData && expected->updates[i].cbData ==
577              got->updates[i].cbData)
578                 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
579                  got->updates[i].cbData), "%s, update %d: unexpected value\n",
580                  header, i);
581         }
582 }
583
584 /* Frees the updates stored in accum */
585 static void free_updates(struct update_accum *accum)
586 {
587     DWORD i;
588
589     for (i = 0; i < accum->cUpdates; i++)
590         CryptMemFree(accum->updates[i].pbData);
591     CryptMemFree(accum->updates);
592     accum->updates = NULL;
593     accum->cUpdates = 0;
594 }
595
596 static void test_data_msg_encoding(void)
597 {
598     HCRYPTMSG msg;
599     BOOL ret;
600     static char oid[] = "1.2.3";
601     struct update_accum accum = { 0, NULL };
602     CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
603
604     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
605      NULL);
606     check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
607      dataEmptyBareContent, sizeof(dataEmptyBareContent));
608     check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
609      sizeof(dataEmptyContent));
610     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
611     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
612     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
613      dataBareContent, sizeof(dataBareContent));
614     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
615      sizeof(dataContent));
616     CryptMsgClose(msg);
617     /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
618     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
619      CMSG_DATA, NULL, NULL, NULL);
620     check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
621      dataEmptyBareContent, sizeof(dataEmptyBareContent));
622     check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
623      sizeof(dataEmptyContent));
624     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
625     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
626     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
627      dataBareContent, sizeof(dataBareContent));
628     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
629      sizeof(dataContent));
630     CryptMsgClose(msg);
631     /* The inner OID is apparently ignored */
632     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
633      NULL);
634     check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
635      dataEmptyBareContent, sizeof(dataEmptyBareContent));
636     check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
637      dataEmptyContent, sizeof(dataEmptyContent));
638     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
639     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
640     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
641      dataBareContent, sizeof(dataBareContent));
642     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
643      sizeof(dataContent));
644     CryptMsgClose(msg);
645     /* A streaming message is DER encoded if the length is not 0xffffffff, but
646      * curiously, updates aren't validated to make sure they don't exceed the
647      * stated length.  (The resulting output will of course fail to decode.)
648      */
649     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
650      NULL, &streamInfo);
651     CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
652     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
653     CryptMsgClose(msg);
654     check_updates("bogus data message with definite length", &a1, &accum);
655     free_updates(&accum);
656     /* A valid definite-length encoding: */
657     streamInfo.cbContent = sizeof(msgData);
658     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
659      NULL, &streamInfo);
660     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
661     CryptMsgClose(msg);
662     check_updates("data message with definite length", &a2, &accum);
663     free_updates(&accum);
664     /* An indefinite-length encoding: */
665     streamInfo.cbContent = 0xffffffff;
666     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
667      NULL, &streamInfo);
668     CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
669     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
670     CryptMsgClose(msg);
671     check_updates("data message with indefinite length", &a3, &accum);
672     free_updates(&accum);
673 }
674
675 static void test_data_msg(void)
676 {
677     test_data_msg_open();
678     test_data_msg_update();
679     test_data_msg_get_param();
680     test_data_msg_encoding();
681 }
682
683 static void test_hash_msg_open(void)
684 {
685     HCRYPTMSG msg;
686     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
687     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
688
689     SetLastError(0xdeadbeef);
690     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
691      NULL, NULL);
692     ok(!msg && GetLastError() == E_INVALIDARG,
693      "Expected E_INVALIDARG, got %x\n", GetLastError());
694     hashInfo.cbSize = sizeof(hashInfo);
695     SetLastError(0xdeadbeef);
696     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
697      NULL, NULL);
698     ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
699      "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
700     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
701     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
702      NULL, NULL);
703     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
704     CryptMsgClose(msg);
705     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
706      CMSG_HASHED, &hashInfo, NULL, NULL);
707     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
708     CryptMsgClose(msg);
709     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
710      CMSG_HASHED, &hashInfo, NULL, &streamInfo);
711     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
712     CryptMsgClose(msg);
713 }
714
715 static void test_hash_msg_update(void)
716 {
717     HCRYPTMSG msg;
718     BOOL ret;
719     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
720      { oid_rsa_md5, { 0, NULL } }, NULL };
721     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
722
723     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
724      CMSG_HASHED, &hashInfo, NULL, NULL);
725     /* Detached hashed messages opened in non-streaming mode allow non-final
726      * updates..
727      */
728     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
729     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
730     /* including non-final updates with no data.. */
731     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
732     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
733     /* and final updates with no data. */
734     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
735     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
736     /* But no updates are allowed after the final update. */
737     SetLastError(0xdeadbeef);
738     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
739     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
740      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
741     SetLastError(0xdeadbeef);
742     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
743     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
744      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
745     CryptMsgClose(msg);
746     /* Non-detached messages, in contrast, don't allow non-final updates in
747      * non-streaming mode.
748      */
749     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
750      NULL, NULL);
751     SetLastError(0xdeadbeef);
752     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
753     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
754      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
755     /* Final updates (including empty ones) are allowed. */
756     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
757     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
758     CryptMsgClose(msg);
759     /* And, of course, streaming mode allows non-final updates */
760     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
761      NULL, &streamInfo);
762     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
763     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
764     CryptMsgClose(msg);
765     /* Setting pfnStreamOutput to NULL results in no error.  (In what appears
766      * to be a bug, it isn't actually used - see encoding tests.)
767      */
768     streamInfo.pfnStreamOutput = NULL;
769     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
770      NULL, &streamInfo);
771     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
772     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
773     CryptMsgClose(msg);
774 }
775
776 static const BYTE emptyHashParam[] = {
777 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
778 0x7e };
779
780 static void test_hash_msg_get_param(void)
781 {
782     HCRYPTMSG msg;
783     BOOL ret;
784     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
785      { oid_rsa_md5, { 0, NULL } }, NULL };
786     DWORD size, value;
787     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
788     BYTE buf[16];
789
790     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
791      NULL, NULL);
792     /* Content and bare content are always gettable for non-streamed messages */
793     size = 0;
794     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
795     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
796     size = 0;
797     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
798     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
799     /* For an encoded hash message, the hash data aren't available */
800     SetLastError(0xdeadbeef);
801     ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
802     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
803      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
804     /* The hash is also available. */
805     size = 0;
806     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
807     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
808     ok(size == sizeof(buf), "Unexpected size %d\n", size);
809     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
810     if (size == sizeof(buf))
811         ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
812     /* By getting the hash, further updates are not allowed */
813     SetLastError(0xdeadbeef);
814     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
815     ok(!ret &&
816        (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
817         GetLastError() == NTE_BAD_ALGID /* 9x */ ||
818         GetLastError() == CRYPT_E_MSG_ERROR /* Vista */),
819        "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
820
821     /* Even after a final update, the hash data aren't available */
822     SetLastError(0xdeadbeef);
823     ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
824     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
825      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
826     /* The version is also available, and should be zero for this message. */
827     size = 0;
828     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
829     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
830     size = sizeof(value);
831     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
832     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
833     ok(value == 0, "Expected version 0, got %d\n", value);
834     /* As usual, the type isn't available. */
835     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
836     ok(!ret, "Expected failure\n");
837     CryptMsgClose(msg);
838
839     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
840      NULL, &streamInfo);
841     /* Streamed messages don't allow you to get the content or bare content. */
842     SetLastError(0xdeadbeef);
843     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
844     ok(!ret && GetLastError() == E_INVALIDARG,
845      "Expected E_INVALIDARG, got %x\n", GetLastError());
846     SetLastError(0xdeadbeef);
847     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
848     ok(!ret && GetLastError() == E_INVALIDARG,
849      "Expected E_INVALIDARG, got %x\n", GetLastError());
850     /* The hash is still available. */
851     size = 0;
852     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
853     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
854     ok(size == sizeof(buf), "Unexpected size %d\n", size);
855     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
856     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
857     if (size == sizeof(buf))
858         ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
859     /* After updating the hash, further updates aren't allowed on streamed
860      * messages either.
861      */
862     SetLastError(0xdeadbeef);
863     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
864     ok(!ret &&
865        (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
866         GetLastError() == NTE_BAD_ALGID /* 9x */ ||
867         GetLastError() == CRYPT_E_MSG_ERROR /* Vista */),
868        "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
869
870     CryptMsgClose(msg);
871 }
872
873 static const BYTE hashEmptyBareContent[] = {
874 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
875 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
876 static const BYTE hashEmptyContent[] = {
877 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
878 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
879 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
880 static const BYTE hashBareContent[] = {
881 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
882 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
883 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
884 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
885 static const BYTE hashContent[] = {
886 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
887 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
888 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
889 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
890 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
891
892 static const BYTE detachedHashNonFinalBareContent[] = {
893 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
894 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
895 0x07,0x01,0x04,0x00 };
896 static const BYTE detachedHashNonFinalContent[] = {
897 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
898 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
899 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
900 0x07,0x01,0x04,0x00 };
901 static const BYTE detachedHashBareContent[] = {
902 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
903 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
904 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
905 0x9d,0x2a,0x8f,0x26,0x2f };
906 static const BYTE detachedHashContent[] = {
907 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
908 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
909 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
910 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
911 0x9d,0x2a,0x8f,0x26,0x2f };
912
913 static void test_hash_msg_encoding(void)
914 {
915     HCRYPTMSG msg;
916     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
917     BOOL ret;
918     struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
919     CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
920
921     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
922     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
923      NULL, NULL);
924     check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
925      hashEmptyBareContent, sizeof(hashEmptyBareContent));
926     check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
927      hashEmptyContent, sizeof(hashEmptyContent));
928     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
929     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
930     check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
931      hashBareContent, sizeof(hashBareContent));
932     check_param("hash content", msg, CMSG_CONTENT_PARAM,
933      hashContent, sizeof(hashContent));
934     CryptMsgClose(msg);
935     /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
936     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
937      CMSG_HASHED, &hashInfo, NULL, NULL);
938     check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
939      hashEmptyBareContent, sizeof(hashEmptyBareContent));
940     check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
941      hashEmptyContent, sizeof(hashEmptyContent));
942     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
943     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
944     check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
945      hashBareContent, sizeof(hashBareContent));
946     check_param("hash content", msg, CMSG_CONTENT_PARAM,
947      hashContent, sizeof(hashContent));
948     CryptMsgClose(msg);
949     /* Same test, but with CMSG_DETACHED_FLAG set */
950     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
951      CMSG_HASHED, &hashInfo, NULL, NULL);
952     check_param("detached hash empty bare content", msg,
953      CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
954      sizeof(hashEmptyBareContent));
955     check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
956      hashEmptyContent, sizeof(hashEmptyContent));
957     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
958     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
959     check_param("detached hash not final bare content", msg,
960      CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
961      sizeof(detachedHashNonFinalBareContent));
962     check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
963      detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
964     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
965     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
966     check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
967      detachedHashBareContent, sizeof(detachedHashBareContent));
968     check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
969      detachedHashContent, sizeof(detachedHashContent));
970     check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
971      detachedHashBareContent, sizeof(detachedHashBareContent));
972     check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
973      detachedHashContent, sizeof(detachedHashContent));
974     CryptMsgClose(msg);
975     /* In what appears to be a bug, streamed updates to hash messages don't
976      * call the output function.
977      */
978     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
979      NULL, &streamInfo);
980     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
981     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
982     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
983     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
984     CryptMsgClose(msg);
985     check_updates("empty hash message", &empty_accum, &accum);
986     free_updates(&accum);
987
988     streamInfo.cbContent = sizeof(msgData);
989     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
990      NULL, &streamInfo);
991     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
992     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
993     CryptMsgClose(msg);
994     check_updates("hash message", &empty_accum, &accum);
995     free_updates(&accum);
996
997     streamInfo.cbContent = sizeof(msgData);
998     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
999      CMSG_HASHED, &hashInfo, NULL, &streamInfo);
1000     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1001     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1002     CryptMsgClose(msg);
1003     check_updates("detached hash message", &empty_accum, &accum);
1004     free_updates(&accum);
1005 }
1006
1007 static void test_hash_msg(void)
1008 {
1009     test_hash_msg_open();
1010     test_hash_msg_update();
1011     test_hash_msg_get_param();
1012     test_hash_msg_encoding();
1013 }
1014
1015 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1016  'm','p',0 };
1017 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1018  'm','p',0 };
1019 static BYTE serialNum[] = { 1 };
1020 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1021  0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1022
1023 static void test_signed_msg_open(void)
1024 {
1025     HCRYPTMSG msg;
1026     BOOL ret;
1027     CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1028     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1029     CERT_INFO certInfo = { 0 };
1030
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     signInfo.cbSize = sizeof(signInfo);
1037     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1038      NULL, NULL);
1039     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1040     CryptMsgClose(msg);
1041
1042     signInfo.cSigners = 1;
1043     signInfo.rgSigners = &signer;
1044     /* With signer.pCertInfo unset, attempting to open this message this
1045      * crashes.
1046      */
1047     signer.pCertInfo = &certInfo;
1048     /* The cert info must contain a serial number and an issuer. */
1049     SetLastError(0xdeadbeef);
1050     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1051      NULL, NULL);
1052     /* NT: E_INVALIDARG, 9x: unchanged */
1053     ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef),
1054        "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError());
1055
1056     certInfo.SerialNumber.cbData = sizeof(serialNum);
1057     certInfo.SerialNumber.pbData = serialNum;
1058     SetLastError(0xdeadbeef);
1059     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1060      NULL, NULL);
1061     /* NT: E_INVALIDARG, 9x: unchanged */
1062     ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef),
1063        "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError());
1064
1065     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1066     certInfo.Issuer.pbData = encodedCommonName;
1067     SetLastError(0xdeadbeef);
1068     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1069      NULL, NULL);
1070     ok(!msg && GetLastError() == E_INVALIDARG,
1071      "Expected E_INVALIDARG, got %x\n", GetLastError());
1072
1073     /* The signer's hCryptProv must be set to something.  Whether it's usable
1074      * or not will be checked after the hash algorithm is checked (see next
1075      * test.)
1076      */
1077     signer.hCryptProv = 1;
1078     SetLastError(0xdeadbeef);
1079     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1080      NULL, NULL);
1081     ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1082      "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1083     /* The signer's hash algorithm must also be set. */
1084     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1085     SetLastError(0xdeadbeef);
1086     /* Crashes in advapi32 in wine, don't do it */
1087     if (0) {
1088         msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1089          &signInfo, NULL, NULL);
1090         ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1091          "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1092     }
1093     /* The signer's hCryptProv must also be valid. */
1094     ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1095                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1096     if (!ret && GetLastError() == NTE_EXISTS) {
1097         ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1098                                     PROV_RSA_FULL, 0);
1099     }
1100     ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1101
1102     if (ret) {
1103         msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1104                                    NULL, NULL);
1105         ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1106         CryptMsgClose(msg);
1107     }
1108
1109     /* pCertInfo must still be set, but can be empty if the SignerId's issuer
1110      * and serial number are set.
1111      */
1112     certInfo.Issuer.cbData = 0;
1113     certInfo.SerialNumber.cbData = 0;
1114     signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1115     U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1116      sizeof(encodedCommonName);
1117     U(signer.SignerId).IssuerSerialNumber.Issuer.pbData =
1118      (BYTE *)encodedCommonName;
1119     U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1120      sizeof(serialNum);
1121     U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
1122     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1123      NULL, NULL);
1124     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1125     CryptMsgClose(msg);
1126
1127     CryptReleaseContext(signer.hCryptProv, 0);
1128     pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1129      PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1130 }
1131
1132 static const BYTE privKey[] = {
1133  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1134  0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1135  0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1136  0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1137  0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1138  0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1139  0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1140  0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1141  0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1142  0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1143  0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1144  0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1145  0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1146  0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1147  0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1148  0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1149  0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1150  0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1151  0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1152  0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1153  0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1154  0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1155  0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1156  0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1157 static BYTE pubKey[] = {
1158 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1159 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1160 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1161 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1162 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1163
1164 static void test_signed_msg_update(void)
1165 {
1166     HCRYPTMSG msg;
1167     BOOL ret;
1168     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1169     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1170     CERT_INFO certInfo = { 0 };
1171     HCRYPTKEY key;
1172
1173     certInfo.SerialNumber.cbData = sizeof(serialNum);
1174     certInfo.SerialNumber.pbData = serialNum;
1175     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1176     certInfo.Issuer.pbData = encodedCommonName;
1177     signer.pCertInfo = &certInfo;
1178     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1179     signInfo.cSigners = 1;
1180     signInfo.rgSigners = &signer;
1181
1182     ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1183                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1184     if (!ret && GetLastError() == NTE_EXISTS) {
1185         ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1186                                     PROV_RSA_FULL, 0);
1187     }
1188     ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1189
1190     if (!ret) {
1191         skip("No context for tests\n");
1192         return;
1193     }
1194
1195     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1196      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1197     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1198     /* Detached CMSG_SIGNED allows non-final updates. */
1199     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1200     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1201     /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1202     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1203     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1204     /* The final update requires a private key in the hCryptProv, in order to
1205      * generate the signature.
1206      */
1207     SetLastError(0xdeadbeef);
1208     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1209     ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1210      GetLastError() == NTE_NO_KEY),
1211      "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1212     ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1213      0, 0, &key);
1214     ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1215     /* The final update should be able to succeed now that a key exists, but
1216      * the previous (invalid) final update prevents it.
1217      */
1218     SetLastError(0xdeadbeef);
1219     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1220     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1221      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1222     CryptMsgClose(msg);
1223
1224     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1225      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1226     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1227     /* Detached CMSG_SIGNED allows non-final updates. */
1228     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1229     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1230     /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1231     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1232     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1233     /* Now that the private key exists, the final update can succeed (even
1234      * with no data.)
1235      */
1236     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1237     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1238     /* But no updates are allowed after the final update. */
1239     SetLastError(0xdeadbeef);
1240     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1241     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1242      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1243     SetLastError(0xdeadbeef);
1244     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1245     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1246      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1247     CryptMsgClose(msg);
1248
1249     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1250      NULL, NULL);
1251     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1252     /* Non-detached messages don't allow non-final updates.. */
1253     SetLastError(0xdeadbeef);
1254     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1255     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1256      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1257     /* but they do allow final ones. */
1258     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1259     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1260     CryptMsgClose(msg);
1261     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1262      NULL, NULL);
1263     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1264     /* They also allow final updates with no data. */
1265     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1266     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1267     CryptMsgClose(msg);
1268
1269     CryptDestroyKey(key);
1270     CryptReleaseContext(signer.hCryptProv, 0);
1271     pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1272      CRYPT_DELETEKEYSET);
1273 }
1274
1275 static const BYTE signedEmptyBareContent[] = {
1276 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1277 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1278 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1279 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1280 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1281 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1282 static const BYTE signedEmptyContent[] = {
1283 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1284 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1285 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1286 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1287 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1288 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1289 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1290 static const BYTE detachedSignedBareContent[] = {
1291 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1292 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1293 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1294 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1295 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1296 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1297 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1298 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1299 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1300 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1301 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1302 static const BYTE detachedSignedContent[] = {
1303 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1304 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1305 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1306 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1307 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1308 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1309 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1310 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1311 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1312 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1313 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1314 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1315 static const BYTE signedBareContent[] = {
1316 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1317 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1318 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1319 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1320 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1321 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1322 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1323 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1324 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1325 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1326 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1327 static const BYTE signedContent[] = {
1328 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1329 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1330 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1331 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1332 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1333 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1334 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1335 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1336 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1337 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1338 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1339 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1340 0x0d };
1341 static const BYTE signedHash[] = {
1342 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1343 0x2f };
1344 static const BYTE signedKeyIdEmptyContent[] = {
1345 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
1346 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1347 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
1348 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1349 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1350 static const BYTE signedEncodedSigner[] = {
1351 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1352 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1353 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1354 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1355 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1356 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1357 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1358 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1359 static const BYTE signedWithAuthAttrsBareContent[] = {
1360 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1361 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1362 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1363 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1364 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1365 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1366 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1367 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1368 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1369 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1370 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1371 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1372 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1373 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1374 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1375 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1376 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1377 0xff,0xc6,0x33,0x63,0x34 };
1378 static BYTE cert[] = {
1379 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1380 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1381 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1382 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1383 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1384 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1385 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1386 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1387 0xff,0x02,0x01,0x01 };
1388 static BYTE v1CertWithPubKey[] = {
1389 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1390 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1391 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1392 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1393 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1394 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1395 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1396 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1397 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1398 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1399 0x01,0x01 };
1400 static const BYTE signedWithCertEmptyBareContent[] = {
1401 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1402 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1403 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1404 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1405 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1406 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1407 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1408 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1409 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1410 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1411 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1412 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1413 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1414 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1415 static const BYTE signedWithCertBareContent[] = {
1416 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1417 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1418 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1419 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1420 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1421 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1422 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1423 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1424 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1425 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1426 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1427 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1428 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1429 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1430 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1431 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1432 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1433 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1434 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1435 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1436 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1437 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1438 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1439 0x30,0x30,0x30,0x30,0x5a };
1440 static const BYTE signedWithCrlEmptyBareContent[] = {
1441 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1442 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1443 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1444 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1445 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1446 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1447 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1448 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1449 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1450 static const BYTE signedWithCrlBareContent[] = {
1451 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1452 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1453 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1454 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1455 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1456 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1457 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1458 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1459 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1460 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1461 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1462 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1463 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1464 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1465 0xa8,0x0d };
1466 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1467 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1468 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1469 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1470 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1471 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1472 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1473 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1474 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1475 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1476 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1477 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1478 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1479 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1480 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1481 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1482 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1483 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1484 0x04,0x00 };
1485 static const BYTE signedWithCertAndCrlBareContent[] = {
1486 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1487 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1488 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1489 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1490 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1491 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1492 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1493 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1494 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1495 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1496 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1497 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1498 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1499 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1500 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1501 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1502 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1503 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1504 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1505 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1506 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1507 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1508 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1509 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1510 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1511 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1512 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1513 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1514 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1515 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1516 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1517 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1518 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1519 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1520 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1521 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1522 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1523 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1524 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1525 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1526 static BYTE v1CertWithValidPubKey[] = {
1527 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1528 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1529 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1530 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1531 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1532 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1533 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1534 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1535 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1536 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1537 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1538 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1539 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1540 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1541 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1542 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1543 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1544 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1545 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1546 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1547 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1548 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1549 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1550 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1551 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1552 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1553 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1554 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1555 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1556 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1557 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1558 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1559 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1560 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1561 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1562 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1563 0x00 };
1564 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1565 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1566 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1567 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1568 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1569 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1570 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1571 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1572 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1573 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1574 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1575 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1576 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1577 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1578 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1579 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1580 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1581 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1582 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1583 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1584 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1585 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1586 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1587 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1588 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1589 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1590 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1591 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1592
1593 static void test_signed_msg_encoding(void)
1594 {
1595     HCRYPTMSG msg;
1596     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1597     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1598     CERT_INFO certInfo = { 0 };
1599     CERT_BLOB encodedCert = { sizeof(cert), cert };
1600     CRL_BLOB encodedCrl = { sizeof(crl), crl };
1601     char oid_common_name[] = szOID_COMMON_NAME;
1602     CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1603      encodedCommonName };
1604     CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1605     BOOL ret;
1606     HCRYPTKEY key;
1607     DWORD size;
1608
1609     certInfo.SerialNumber.cbData = sizeof(serialNum);
1610     certInfo.SerialNumber.pbData = serialNum;
1611     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1612     certInfo.Issuer.pbData = encodedCommonName;
1613     signer.pCertInfo = &certInfo;
1614     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1615     signInfo.cSigners = 1;
1616     signInfo.rgSigners = &signer;
1617
1618     ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1619                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1620     if (!ret && GetLastError() == NTE_EXISTS) {
1621         ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1622                                     PROV_RSA_FULL, 0);
1623     }
1624     ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1625
1626     if (!ret) {
1627         skip("No context for tests\n");
1628         return;
1629     }
1630
1631     ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1632      0, 0, &key);
1633     ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1634
1635     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1636      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1637     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1638
1639     check_param("detached signed empty bare content", msg,
1640      CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1641      sizeof(signedEmptyBareContent));
1642     check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1643      signedEmptyContent, sizeof(signedEmptyContent));
1644     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1645     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1646     check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1647      signedHash, sizeof(signedHash));
1648     check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1649      detachedSignedBareContent, sizeof(detachedSignedBareContent));
1650     check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1651      detachedSignedContent, sizeof(detachedSignedContent));
1652     SetLastError(0xdeadbeef);
1653     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1654     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1655      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1656     check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1657      signedEncodedSigner, sizeof(signedEncodedSigner));
1658
1659     CryptMsgClose(msg);
1660
1661     certInfo.SerialNumber.cbData = 0;
1662     certInfo.Issuer.cbData = 0;
1663     signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1664     U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1665     U(signer.SignerId).KeyId.pbData = (BYTE *)serialNum;
1666     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1667      NULL, NULL);
1668     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1669     check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM,
1670      signedKeyIdEmptyContent, sizeof(signedKeyIdEmptyContent));
1671     CryptMsgClose(msg);
1672
1673     certInfo.SerialNumber.cbData = sizeof(serialNum);
1674     certInfo.SerialNumber.pbData = serialNum;
1675     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1676     certInfo.Issuer.pbData = encodedCommonName;
1677     signer.SignerId.dwIdChoice = 0;
1678     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1679      NULL, NULL);
1680     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1681
1682     check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1683      signedEmptyBareContent, sizeof(signedEmptyBareContent));
1684     check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1685      signedEmptyContent, sizeof(signedEmptyContent));
1686     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1687     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1688     check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1689      signedBareContent, sizeof(signedBareContent));
1690     check_param("signed content", msg, CMSG_CONTENT_PARAM,
1691      signedContent, sizeof(signedContent));
1692
1693     CryptMsgClose(msg);
1694
1695     signer.cAuthAttr = 1;
1696     signer.rgAuthAttr = &attr;
1697     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1698      NULL, NULL);
1699     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1700
1701     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1702     check_param("signed with auth attrs bare content", msg,
1703      CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1704      sizeof(signedWithAuthAttrsBareContent));
1705
1706     CryptMsgClose(msg);
1707
1708     signer.cAuthAttr = 0;
1709     signInfo.rgCertEncoded = &encodedCert;
1710     signInfo.cCertEncoded = 1;
1711     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1712      NULL, NULL);
1713     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1714
1715     check_param("signed with cert empty bare content", msg,
1716      CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1717      sizeof(signedWithCertEmptyBareContent));
1718     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1719     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1720     check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1721      signedWithCertBareContent, sizeof(signedWithCertBareContent));
1722
1723     CryptMsgClose(msg);
1724
1725     signInfo.cCertEncoded = 0;
1726     signInfo.rgCrlEncoded = &encodedCrl;
1727     signInfo.cCrlEncoded = 1;
1728     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1729      NULL, NULL);
1730     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1731
1732     check_param("signed with crl empty bare content", msg,
1733      CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1734      sizeof(signedWithCrlEmptyBareContent));
1735     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1736     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1737     check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1738      signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1739
1740     CryptMsgClose(msg);
1741
1742     signInfo.cCertEncoded = 1;
1743     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1744      NULL, NULL);
1745     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1746
1747     check_param("signed with cert and crl empty bare content", msg,
1748      CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1749      sizeof(signedWithCertAndCrlEmptyBareContent));
1750     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1751     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1752     check_param("signed with cert and crl bare content", msg,
1753      CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1754      sizeof(signedWithCertAndCrlBareContent));
1755
1756     CryptMsgClose(msg);
1757
1758     /* Test with a cert with a (bogus) public key */
1759     signInfo.cCrlEncoded = 0;
1760     encodedCert.cbData = sizeof(v1CertWithPubKey);
1761     encodedCert.pbData = v1CertWithPubKey;
1762     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1763      NULL, NULL);
1764     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1765     check_param("signedWithCertWithPubKeyBareContent", msg,
1766      CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1767      sizeof(signedWithCertWithPubKeyBareContent));
1768     CryptMsgClose(msg);
1769
1770     encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1771     encodedCert.pbData = v1CertWithValidPubKey;
1772     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1773      NULL, NULL);
1774     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1775     check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1776      CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1777      sizeof(signedWithCertWithValidPubKeyEmptyContent));
1778     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1779     check_param("signedWithCertWithValidPubKeyContent", msg,
1780      CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1781      sizeof(signedWithCertWithValidPubKeyContent));
1782     CryptMsgClose(msg);
1783
1784     CryptDestroyKey(key);
1785     CryptReleaseContext(signer.hCryptProv, 0);
1786     pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1787      CRYPT_DELETEKEYSET);
1788 }
1789
1790 static void test_signed_msg_get_param(void)
1791 {
1792     BOOL ret;
1793     HCRYPTMSG msg;
1794     DWORD size, value = 0;
1795     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1796     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1797     CERT_INFO certInfo = { 0 };
1798
1799     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1800      NULL, NULL);
1801     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1802
1803     /* Content and bare content are always gettable */
1804     size = 0;
1805     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1806     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1807     size = 0;
1808     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1809     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1810     /* For "signed" messages, so is the version. */
1811     size = 0;
1812     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1813     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1814     size = sizeof(value);
1815     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1816     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1817     ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1818     /* But for this message, with no signers, the hash and signer aren't
1819      * available.
1820      */
1821     size = 0;
1822     SetLastError(0xdeadbeef);
1823     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1824     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1825      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1826     SetLastError(0xdeadbeef);
1827     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1828     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1829      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1830     /* As usual, the type isn't available. */
1831     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1832     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1833      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1834
1835     CryptMsgClose(msg);
1836
1837     certInfo.SerialNumber.cbData = sizeof(serialNum);
1838     certInfo.SerialNumber.pbData = serialNum;
1839     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1840     certInfo.Issuer.pbData = encodedCommonName;
1841     signer.pCertInfo = &certInfo;
1842     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1843     signInfo.cSigners = 1;
1844     signInfo.rgSigners = &signer;
1845
1846     ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1847                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1848     if (!ret && GetLastError() == NTE_EXISTS) {
1849         ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1850                                     PROV_RSA_FULL, 0);
1851     }
1852     ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1853
1854     if (!ret) {
1855         skip("No context for tests\n");
1856         return;
1857     }
1858
1859     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1860      NULL, NULL);
1861     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1862
1863     /* This message, with one signer, has the hash and signer for index 0
1864      * available, but not for other indexes.
1865      */
1866     size = 0;
1867     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1868     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1869     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1870     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1871     size = 0;
1872     SetLastError(0xdeadbeef);
1873     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1874     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1875      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1876     SetLastError(0xdeadbeef);
1877     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1878     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1879      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1880     /* As usual, the type isn't available. */
1881     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1882     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1883      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1884
1885     CryptMsgClose(msg);
1886
1887     /* Opening the message using the CMS fields.. */
1888     certInfo.SerialNumber.cbData = 0;
1889     certInfo.Issuer.cbData = 0;
1890     signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1891     U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1892      sizeof(encodedCommonName);
1893     U(signer.SignerId).IssuerSerialNumber.Issuer.pbData =
1894      (BYTE *)encodedCommonName;
1895     U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1896      sizeof(serialNum);
1897     U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
1898     ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1899      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1900     if (!ret && GetLastError() == NTE_EXISTS)
1901         ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1902          PROV_RSA_FULL, 0);
1903     ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1904     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1905      CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1906     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1907     /* still results in the version being 1 when the issuer and serial number
1908      * are used and no additional CMS fields are used.
1909      */
1910     size = sizeof(value);
1911     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1912     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1913     ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value);
1914     /* Apparently the encoded signer can be retrieved.. */
1915     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1916     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1917     /* but the signer info, CMS signer info, and cert ID can't be. */
1918     SetLastError(0xdeadbeef);
1919     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1920     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1921      "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1922     SetLastError(0xdeadbeef);
1923     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1924     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1925      "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1926     SetLastError(0xdeadbeef);
1927     ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1928     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1929      "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1930     CryptMsgClose(msg);
1931
1932     /* Using the KeyId field of the SignerId results in the version becoming
1933      * the CMS version.
1934      */
1935     signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1936     U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1937     U(signer.SignerId).KeyId.pbData = (BYTE *)serialNum;
1938     ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1939      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1940     if (!ret && GetLastError() == NTE_EXISTS)
1941         ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1942          PROV_RSA_FULL, 0);
1943     ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1944     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1945      CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1946     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1947     size = sizeof(value);
1948     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1949     ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value);
1950     /* Even for a CMS message, the signer can be retrieved.. */
1951     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1952     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1953     /* but the signer info, CMS signer info, and cert ID can't be. */
1954     SetLastError(0xdeadbeef);
1955     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1956     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1957      "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1958     SetLastError(0xdeadbeef);
1959     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1960     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1961      "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1962     SetLastError(0xdeadbeef);
1963     ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1964     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1965      "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1966     CryptMsgClose(msg);
1967
1968     CryptReleaseContext(signer.hCryptProv, 0);
1969     pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1970      PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1971 }
1972
1973 static void test_signed_msg(void)
1974 {
1975     test_signed_msg_open();
1976     test_signed_msg_update();
1977     test_signed_msg_encoding();
1978     test_signed_msg_get_param();
1979 }
1980
1981 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1982 static const struct update_accum a4 = { 1, &b4 };
1983
1984 static const BYTE bogusOIDContent[] = {
1985 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1986 0x04,0x00 };
1987 static const BYTE bogusHashContent[] = {
1988 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1989 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1990 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1991 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1992 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1993
1994 static void test_decode_msg_update(void)
1995 {
1996     HCRYPTMSG msg;
1997     BOOL ret;
1998     CMSG_STREAM_INFO streamInfo = { 0 };
1999     DWORD i;
2000     struct update_accum accum = { 0, NULL };
2001
2002     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2003     /* Update with a full message in a final update */
2004     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2005     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2006     /* Can't update after a final update */
2007     SetLastError(0xdeadbeef);
2008     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2009     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2010      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2011     CryptMsgClose(msg);
2012
2013     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2014     /* Can't send a non-final update without streaming */
2015     SetLastError(0xdeadbeef);
2016     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2017      FALSE);
2018     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2019      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2020     /* A subsequent final update succeeds */
2021     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2022     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2023     CryptMsgClose(msg);
2024
2025     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2026     /* Updating a message that has a NULL stream callback fails */
2027     SetLastError(0xdeadbeef);
2028     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2029      FALSE);
2030     todo_wine
2031     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2032      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
2033     /* Changing the callback pointer after the fact yields the same error (so
2034      * the message must copy the stream info, not just store a pointer to it)
2035      */
2036     streamInfo.pfnStreamOutput = nop_stream_output;
2037     SetLastError(0xdeadbeef);
2038     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2039      FALSE);
2040     todo_wine
2041     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2042      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
2043     CryptMsgClose(msg);
2044
2045     /* Empty non-final updates are allowed when streaming.. */
2046     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2047     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2048     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2049     /* but final updates aren't when not enough data has been received. */
2050     SetLastError(0xdeadbeef);
2051     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2052     todo_wine
2053     ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2054      "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2055     CryptMsgClose(msg);
2056
2057     /* Updating the message byte by byte is legal */
2058     streamInfo.pfnStreamOutput = accumulating_stream_output;
2059     streamInfo.pvArg = &accum;
2060     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2061     for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2062         ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2063     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2064     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2065     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2066     CryptMsgClose(msg);
2067     todo_wine
2068     check_updates("byte-by-byte empty content", &a4, &accum);
2069     free_updates(&accum);
2070
2071     /* Decoding bogus content fails in non-streaming mode.. */
2072     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2073     SetLastError(0xdeadbeef);
2074     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2075     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2076      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2077     CryptMsgClose(msg);
2078     /* and as the final update in streaming mode.. */
2079     streamInfo.pfnStreamOutput = nop_stream_output;
2080     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2081     SetLastError(0xdeadbeef);
2082     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2083     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2084      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2085     CryptMsgClose(msg);
2086     /* and even as a non-final update in streaming mode. */
2087     streamInfo.pfnStreamOutput = nop_stream_output;
2088     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2089     SetLastError(0xdeadbeef);
2090     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2091     todo_wine
2092     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2093      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2094     CryptMsgClose(msg);
2095
2096     /* An empty message can be opened with undetermined type.. */
2097     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2098     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2099      TRUE);
2100     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2101     CryptMsgClose(msg);
2102     /* but decoding it as an explicitly typed message fails. */
2103     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2104      NULL);
2105     SetLastError(0xdeadbeef);
2106     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2107      TRUE);
2108     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2109      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2110     CryptMsgClose(msg);
2111     /* On the other hand, decoding the bare content of an empty message fails
2112      * with unspecified type..
2113      */
2114     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2115     SetLastError(0xdeadbeef);
2116     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2117      sizeof(dataEmptyBareContent), TRUE);
2118     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2119      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2120     CryptMsgClose(msg);
2121     /* but succeeds with explicit type. */
2122     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2123      NULL);
2124     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2125      sizeof(dataEmptyBareContent), TRUE);
2126     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2127     CryptMsgClose(msg);
2128
2129     /* Decoding valid content with an unsupported OID fails */
2130     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2131     SetLastError(0xdeadbeef);
2132     ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2133     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2134      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2135     CryptMsgClose(msg);
2136
2137     /* Similarly, opening an empty hash with unspecified type succeeds.. */
2138     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2139     SetLastError(0xdeadbeef);
2140     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2141     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2142     CryptMsgClose(msg);
2143     /* while with specified type it fails. */
2144     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2145      NULL);
2146     SetLastError(0xdeadbeef);
2147     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2148     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2149      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2150     CryptMsgClose(msg);
2151     /* On the other hand, decoding the bare content of an empty hash message
2152      * fails with unspecified type..
2153      */
2154     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2155     SetLastError(0xdeadbeef);
2156     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2157      sizeof(hashEmptyBareContent), TRUE);
2158     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2159      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2160     CryptMsgClose(msg);
2161     /* but succeeds with explicit type. */
2162     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2163      NULL);
2164     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2165      sizeof(hashEmptyBareContent), TRUE);
2166     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2167     CryptMsgClose(msg);
2168
2169     /* And again, opening a (non-empty) hash message with unspecified type
2170      * succeeds..
2171      */
2172     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2173     SetLastError(0xdeadbeef);
2174     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2175     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2176     CryptMsgClose(msg);
2177     /* while with specified type it fails.. */
2178     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2179      NULL);
2180     SetLastError(0xdeadbeef);
2181     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2182     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2183      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2184     CryptMsgClose(msg);
2185     /* and decoding the bare content of a non-empty hash message fails with
2186      * unspecified type..
2187      */
2188     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2189     SetLastError(0xdeadbeef);
2190     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2191     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2192      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2193     CryptMsgClose(msg);
2194     /* but succeeds with explicit type. */
2195     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2196      NULL);
2197     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2198     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2199     CryptMsgClose(msg);
2200
2201     /* Opening a (non-empty) hash message with unspecified type and a bogus
2202      * hash value succeeds..
2203      */
2204     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2205     SetLastError(0xdeadbeef);
2206     ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2207     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2208     CryptMsgClose(msg);
2209
2210     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2211     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2212     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2213     CryptMsgClose(msg);
2214     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2215     SetLastError(0xdeadbeef);
2216     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2217      sizeof(signedWithCertAndCrlBareContent), TRUE);
2218     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2219      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2220     CryptMsgClose(msg);
2221     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2222      NULL);
2223     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2224      sizeof(signedWithCertAndCrlBareContent), TRUE);
2225     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2226     CryptMsgClose(msg);
2227
2228     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2229      NULL, NULL);
2230     /* The first update succeeds.. */
2231     ret = CryptMsgUpdate(msg, detachedSignedContent,
2232      sizeof(detachedSignedContent), TRUE);
2233     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2234     /* as does a second (probably to update the detached portion).. */
2235     ret = CryptMsgUpdate(msg, detachedSignedContent,
2236      sizeof(detachedSignedContent), TRUE);
2237     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2238     /* while a third fails. */
2239     ret = CryptMsgUpdate(msg, detachedSignedContent,
2240      sizeof(detachedSignedContent), TRUE);
2241     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2242      "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2243     CryptMsgClose(msg);
2244
2245     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2246     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2247     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2248     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2249     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2250     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2251     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2252     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2253     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2254
2255     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2256     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2257      "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2258     CryptMsgClose(msg);
2259 }
2260
2261 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2262  0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2263
2264 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2265  const CMSG_SIGNER_INFO *expected)
2266 {
2267     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2268      expected->dwVersion, got->dwVersion);
2269     ok(got->Issuer.cbData == expected->Issuer.cbData,
2270      "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2271      got->Issuer.cbData);
2272     ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2273      "Unexpected issuer\n");
2274     ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2275      "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2276      got->SerialNumber.cbData);
2277     ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2278      got->SerialNumber.cbData), "Unexpected serial number\n");
2279     /* FIXME: check more things */
2280 }
2281
2282 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2283  const CMSG_CMS_SIGNER_INFO *expected)
2284 {
2285     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2286      expected->dwVersion, got->dwVersion);
2287     ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2288      "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2289      got->SignerId.dwIdChoice);
2290     if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2291     {
2292         if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2293         {
2294             ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2295              U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2296              "Expected issuer size %d, got %d\n",
2297              U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2298              U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2299             ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2300              U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2301              U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2302              "Unexpected issuer\n");
2303             ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2304              U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2305              "Expected serial number size %d, got %d\n",
2306              U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2307              U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2308             ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2309              U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2310              U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2311              "Unexpected serial number\n");
2312         }
2313         else
2314         {
2315             ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2316              "expected key id size %d, got %d\n",
2317              U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2318             ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2319              U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2320              "unexpected key id\n");
2321         }
2322     }
2323     /* FIXME: check more things */
2324 }
2325
2326 static const BYTE signedWithCertAndCrlComputedHash[] = {
2327 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2328 0x2f };
2329 static BYTE keyIdIssuer[] = {
2330 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2331 0x0a,0x07,0x01,0x04,0x01,0x01 };
2332
2333 static void test_decode_msg_get_param(void)
2334 {
2335     HCRYPTMSG msg;
2336     BOOL ret;
2337     DWORD size = 0, value;
2338     LPBYTE buf;
2339
2340     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2341     SetLastError(0xdeadbeef);
2342     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2343     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2344      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2345     ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2346     check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2347      sizeof(msgData));
2348     CryptMsgClose(msg);
2349
2350     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2351     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2352     check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2353     check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2354     check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2355      emptyHashParam, sizeof(emptyHashParam));
2356     CryptMsgClose(msg);
2357     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2358     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2359     check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2360      sizeof(msgData));
2361     check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2362      sizeof(hashParam));
2363     check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2364      hashParam, sizeof(hashParam));
2365     /* Curiously, getting the hash of index 1 succeeds, even though there's
2366      * only one hash.
2367      */
2368     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2369     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2370     buf = CryptMemAlloc(size);
2371     if (buf)
2372     {
2373         ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2374         ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2375         ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2376         CryptMemFree(buf);
2377     }
2378     check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2379      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2380     value = CMSG_HASHED_DATA_V0;
2381     check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2382      sizeof(value));
2383     CryptMsgClose(msg);
2384
2385     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2386     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2387     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2388     check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2389      sizeof(msgData));
2390     check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2391      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2392     size = sizeof(value);
2393     value = 2112;
2394     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2395     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2396     ok(value == 1, "Expected 1 signer, got %d\n", value);
2397     size = 0;
2398     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2399     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2400     if (ret)
2401         buf = CryptMemAlloc(size);
2402     else
2403         buf = NULL;
2404     if (buf)
2405     {
2406         CMSG_SIGNER_INFO signer = { 0 };
2407
2408         signer.dwVersion = 1;
2409         signer.Issuer.cbData = sizeof(encodedCommonName);
2410         signer.Issuer.pbData = encodedCommonName;
2411         signer.SerialNumber.cbData = sizeof(serialNum);
2412         signer.SerialNumber.pbData = serialNum;
2413         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2414         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2415         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2416         CryptMemFree(buf);
2417     }
2418     /* Getting the CMS signer info of a PKCS7 message is possible. */
2419     size = 0;
2420     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2421     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2422     if (ret)
2423         buf = CryptMemAlloc(size);
2424     else
2425         buf = NULL;
2426     if (buf)
2427     {
2428         CMSG_CMS_SIGNER_INFO signer = { 0 };
2429
2430         signer.dwVersion = 1;
2431         signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2432         U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2433          sizeof(encodedCommonName);
2434         U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2435         U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2436          sizeof(serialNum);
2437         U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2438         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2439         CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2440         compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2441         CryptMemFree(buf);
2442     }
2443     /* index is ignored when getting signer count */
2444     size = sizeof(value);
2445     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2446     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2447     ok(value == 1, "Expected 1 signer, got %d\n", value);
2448     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2449     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2450     ok(value == 0, "Expected 0 certs, got %d\n", value);
2451     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2452     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2453     ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2454     CryptMsgClose(msg);
2455     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2456      NULL);
2457     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2458      sizeof(signedWithCertAndCrlBareContent), TRUE);
2459     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2460     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2461     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2462     ok(value == 1, "Expected 1 cert, got %d\n", value);
2463     check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2464     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2465     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2466     ok(value == 1, "Expected 1 CRL, got %d\n", value);
2467     check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2468     check_param("signed with cert and CRL computed hash", msg,
2469      CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2470      sizeof(signedWithCertAndCrlComputedHash));
2471     CryptMsgClose(msg);
2472
2473     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2474     ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
2475      sizeof(signedKeyIdEmptyContent), TRUE);
2476     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2477     size = sizeof(value);
2478     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2479     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2480     ok(value == 1, "Expected 1 signer, got %d\n", value);
2481     /* Getting the regular (non-CMS) signer info from a CMS message is also
2482      * possible..
2483      */
2484     size = 0;
2485     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2486     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2487     if (ret)
2488         buf = CryptMemAlloc(size);
2489     else
2490         buf = NULL;
2491     if (buf)
2492     {
2493         CMSG_SIGNER_INFO signer;
2494         BYTE zero = 0;
2495
2496         /* and here's the little oddity:  for a CMS message using the key id
2497          * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
2498          * a signer with a zero (not empty) serial number, and whose issuer is
2499          * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
2500          * and value of the key id.
2501          */
2502         signer.dwVersion = CMSG_SIGNED_DATA_V3;
2503         signer.Issuer.cbData = sizeof(keyIdIssuer);
2504         signer.Issuer.pbData = keyIdIssuer;
2505         signer.SerialNumber.cbData = 1;
2506         signer.SerialNumber.pbData = &zero;
2507         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2508         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2509         CryptMemFree(buf);
2510     }
2511     size = 0;
2512     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2513     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2514     if (ret)
2515         buf = CryptMemAlloc(size);
2516     else
2517         buf = NULL;
2518     if (buf)
2519     {
2520         CMSG_CMS_SIGNER_INFO signer = { 0 };
2521
2522         signer.dwVersion = CMSG_SIGNED_DATA_V3;
2523         signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2524         U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
2525         U(signer.SignerId).KeyId.pbData = (BYTE *)serialNum;
2526         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2527         CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2528         compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2529         CryptMemFree(buf);
2530     }
2531     CryptMsgClose(msg);
2532 }
2533
2534 static void test_decode_msg(void)
2535 {
2536     test_decode_msg_update();
2537     test_decode_msg_get_param();
2538 }
2539
2540 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2541 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2542 static BYTE encodedPubKey[] = {
2543 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2544 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2545 0x0d,0x0e,0x0f };
2546 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2547 static BYTE mod_encoded[] = {
2548  0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2549  0x01,0x00,0x01 };
2550
2551 static void test_msg_control(void)
2552 {
2553     static char oid_rsa_rsa[] = szOID_RSA_RSA;
2554     BOOL ret;
2555     HCRYPTMSG msg;
2556     DWORD i;
2557     CERT_INFO certInfo = { 0 };
2558     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2559     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2560     CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2561
2562     /* Crashes
2563     ret = CryptMsgControl(NULL, 0, 0, NULL);
2564     */
2565
2566     /* Data encode messages don't allow any sort of control.. */
2567     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2568      NULL);
2569     /* either with no prior update.. */
2570     for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2571     {
2572         SetLastError(0xdeadbeef);
2573         ret = CryptMsgControl(msg, 0, i, NULL);
2574         ok(!ret && GetLastError() == E_INVALIDARG,
2575          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2576     }
2577     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2578     /* or after an update. */
2579     for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2580     {
2581         SetLastError(0xdeadbeef);
2582         ret = CryptMsgControl(msg, 0, i, NULL);
2583         ok(!ret && GetLastError() == E_INVALIDARG,
2584          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2585     }
2586     CryptMsgClose(msg);
2587
2588     /* Hash encode messages don't allow any sort of control.. */
2589     hashInfo.cbSize = sizeof(hashInfo);
2590     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2591     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2592      NULL, NULL);
2593     /* either with no prior update.. */
2594     for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2595     {
2596         SetLastError(0xdeadbeef);
2597         ret = CryptMsgControl(msg, 0, i, NULL);
2598         ok(!ret && GetLastError() == E_INVALIDARG,
2599          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2600     }
2601     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2602     /* or after an update. */
2603     for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2604     {
2605         SetLastError(0xdeadbeef);
2606         ret = CryptMsgControl(msg, 0, i, NULL);
2607         ok(!ret && GetLastError() == E_INVALIDARG,
2608          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2609     }
2610     CryptMsgClose(msg);
2611
2612     /* Signed encode messages likewise don't allow any sort of control.. */
2613     signInfo.cbSize = sizeof(signInfo);
2614     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2615      NULL, NULL);
2616     /* either before an update.. */
2617     for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2618     {
2619         SetLastError(0xdeadbeef);
2620         ret = CryptMsgControl(msg, 0, i, NULL);
2621         ok(!ret && GetLastError() == E_INVALIDARG,
2622          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2623     }
2624     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2625     /* or after an update. */
2626     for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2627     {
2628         SetLastError(0xdeadbeef);
2629         ret = CryptMsgControl(msg, 0, i, NULL);
2630         ok(!ret && GetLastError() == E_INVALIDARG,
2631          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2632     }
2633     CryptMsgClose(msg);
2634
2635     /* Decode messages behave a bit differently. */
2636     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2637     /* Bad control type */
2638     SetLastError(0xdeadbeef);
2639     ret = CryptMsgControl(msg, 0, 0, NULL);
2640     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2641      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2642     SetLastError(0xdeadbeef);
2643     ret = CryptMsgControl(msg, 1, 0, NULL);
2644     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2645      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2646     /* Can't verify the hash of an indeterminate-type message */
2647     SetLastError(0xdeadbeef);
2648     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2649     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2650      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2651     /* Crashes
2652     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2653      */
2654     /* Can't decrypt an indeterminate-type message */
2655     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2656     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2657      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2658     CryptMsgClose(msg);
2659
2660     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2661      NULL);
2662     /* Can't verify the hash of an empty message */
2663     SetLastError(0xdeadbeef);
2664     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2665     todo_wine
2666     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2667      "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2668     /* Crashes
2669     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2670      */
2671     /* Can't verify the signature of a hash message */
2672     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2673     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2674      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2675     CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2676      TRUE);
2677     /* Oddly enough, this fails */
2678     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2679     ok(!ret, "Expected failure\n");
2680     CryptMsgClose(msg);
2681     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2682      NULL);
2683     CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2684     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2685     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2686     /* Can't decrypt an indeterminate-type message */
2687     SetLastError(0xdeadbeef);
2688     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2689     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2690      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2691     CryptMsgClose(msg);
2692
2693     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2694      NULL, NULL);
2695     /* Can't verify the hash of a detached message before it's been updated. */
2696     SetLastError(0xdeadbeef);
2697     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2698     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2699      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2700     ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
2701      TRUE);
2702     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2703     /* Still can't verify the hash of a detached message with the content
2704      * of the detached hash given..
2705      */
2706     SetLastError(0xdeadbeef);
2707     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2708     ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
2709      "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
2710     /* and giving the content of the message after attempting to verify the
2711      * hash fails.
2712      */
2713     SetLastError(0xdeadbeef);
2714     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2715     todo_wine
2716     ok(!ret &&
2717        (GetLastError() == NTE_BAD_HASH_STATE ||
2718         GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
2719      "Expected NTE_BAD_HASH_STATE or CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2720     CryptMsgClose(msg);
2721
2722     /* Finally, verifying the hash of a detached message in the correct order:
2723      * 1. Update with the detached hash message
2724      * 2. Update with the content of the message
2725      * 3. Verifying the hash of the message
2726      * succeeds.
2727      */
2728     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2729      NULL, NULL);
2730     ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
2731      TRUE);
2732     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2733     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2734     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2735     SetLastError(0xdeadbeef);
2736     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2737     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2738     CryptMsgClose(msg);
2739
2740     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2741      NULL);
2742     /* Can't verify the hash of a signed message */
2743     SetLastError(0xdeadbeef);
2744     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2745     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2746      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2747     /* Can't decrypt a signed message */
2748     SetLastError(0xdeadbeef);
2749     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2750     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2751      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2752     /* Crash
2753     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2754     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2755      */
2756     CryptMsgUpdate(msg, signedWithCertBareContent,
2757      sizeof(signedWithCertBareContent), TRUE);
2758     /* With an empty cert info, the signer can't be found in the message (and
2759      * the signature can't be verified.
2760      */
2761     SetLastError(0xdeadbeef);
2762     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2763     ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2764      "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2765     /* The cert info is expected to have an issuer, serial number, and public
2766      * key info set.
2767      */
2768     certInfo.SerialNumber.cbData = sizeof(serialNum);
2769     certInfo.SerialNumber.pbData = serialNum;
2770     certInfo.Issuer.cbData = sizeof(encodedCommonName);
2771     certInfo.Issuer.pbData = encodedCommonName;
2772     SetLastError(0xdeadbeef);
2773     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2774     ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2775      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2776     CryptMsgClose(msg);
2777     /* This cert has a public key, but it's not in a usable form */
2778     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2779      NULL);
2780     CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2781      sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2782     /* Again, cert info needs to have a public key set */
2783     SetLastError(0xdeadbeef);
2784     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2785     ok(!ret &&
2786      (GetLastError() == CRYPT_E_ASN1_EOD ||
2787       GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2788      "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2789     /* The public key is supposed to be in encoded form.. */
2790     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2791     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2792     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2793     SetLastError(0xdeadbeef);
2794     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2795     ok(!ret &&
2796      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2797       GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2798      "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2799     /* but not as a X509_PUBLIC_KEY_INFO.. */
2800     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2801     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2802     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2803     SetLastError(0xdeadbeef);
2804     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2805     ok(!ret &&
2806      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2807       GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2808      "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2809     /* This decodes successfully, but it doesn't match any key in the message */
2810     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2811     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2812     SetLastError(0xdeadbeef);
2813     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2814     /* In Wine's rsaenh, this fails to decode because the key length is too
2815      * small.  Not sure if that's a bug in rsaenh, so leaving todo_wine for
2816      * now.
2817      */
2818     todo_wine
2819     ok(!ret &&
2820      (GetLastError() == NTE_BAD_SIGNATURE ||
2821       GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2822      "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2823     CryptMsgClose(msg);
2824     /* A message with no data doesn't have a valid signature */
2825     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2826     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2827      sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2828     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2829     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2830     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2831     SetLastError(0xdeadbeef);
2832     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2833     ok(!ret &&
2834      (GetLastError() == NTE_BAD_SIGNATURE ||
2835       GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2836      "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2837     CryptMsgClose(msg);
2838     /* Finally, this succeeds */
2839     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2840     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2841      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2842     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2843     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2844     CryptMsgClose(msg);
2845
2846     /* Test verifying signature of a detached signed message */
2847     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2848      NULL, NULL);
2849     ret = CryptMsgUpdate(msg, detachedSignedContent,
2850      sizeof(detachedSignedContent), TRUE);
2851     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2852     /* Can't verify the sig without having updated the data */
2853     SetLastError(0xdeadbeef);
2854     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2855     ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2856      "expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2857     /* Now that the signature's been checked, can't do the final update */
2858     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2859     todo_wine
2860     ok(!ret &&
2861      (GetLastError() == NTE_BAD_HASH_STATE ||
2862       GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
2863      "expected NTE_BAD_HASH_STATE or CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2864     CryptMsgClose(msg);
2865     /* Updating with the detached portion of the message and the data of the
2866      * the message allows the sig to be verified.
2867      */
2868     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2869      NULL, NULL);
2870     ret = CryptMsgUpdate(msg, detachedSignedContent,
2871      sizeof(detachedSignedContent), TRUE);
2872     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2873     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2874     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2875     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2876     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2877     CryptMsgClose(msg);
2878 }
2879
2880 /* win9x has much less parameter checks and will crash on many tests
2881  * this code is from test_signed_msg_update()
2882  */
2883 static BOOL detect_nt(void)
2884 {
2885     BOOL ret;
2886     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
2887     CERT_INFO certInfo = { 0 };
2888
2889     if (!pCryptAcquireContextW)
2890         return FALSE;
2891
2892     certInfo.SerialNumber.cbData = sizeof(serialNum);
2893     certInfo.SerialNumber.pbData = serialNum;
2894     certInfo.Issuer.cbData = sizeof(encodedCommonName);
2895     certInfo.Issuer.pbData = encodedCommonName;
2896     signer.pCertInfo = &certInfo;
2897     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2898
2899     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2900                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
2901     if (!ret && GetLastError() == NTE_EXISTS) {
2902         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2903                                     PROV_RSA_FULL, 0);
2904     }
2905
2906     if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
2907
2908     /* cleanup */
2909     CryptReleaseContext(signer.hCryptProv, 0);
2910     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
2911                           CRYPT_DELETEKEYSET);
2912
2913     return TRUE;
2914 }
2915
2916 static void test_msg_get_and_verify_signer(void)
2917 {
2918     BOOL ret;
2919     HCRYPTMSG msg;
2920     PCCERT_CONTEXT signer;
2921     DWORD signerIndex;
2922     HCERTSTORE store;
2923
2924     /* Crash */
2925     if (0)
2926     {
2927         ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
2928         ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
2929     }
2930
2931     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2932     /* An empty message has no signer */
2933     SetLastError(0xdeadbeef);
2934     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2935     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2936      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2937     /* The signer is cleared on error */
2938     signer = (PCCERT_CONTEXT)0xdeadbeef;
2939     SetLastError(0xdeadbeef);
2940     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2941     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2942      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2943     ok(!signer, "expected signer to be NULL\n");
2944     /* The signer index is also cleared on error */
2945     signerIndex = 0xdeadbeef;
2946     SetLastError(0xdeadbeef);
2947     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2948     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2949      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2950     ok(!signerIndex, "expected 0, got %d\n", signerIndex);
2951     /* An unsigned message (msgData isn't a signed message at all)
2952      * likewise has no signer.
2953      */
2954     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2955     SetLastError(0xdeadbeef);
2956     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2957     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2958      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2959     CryptMsgClose(msg);
2960
2961     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2962     /* A "signed" message created with no signer cert likewise has no signer */
2963     CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
2964     SetLastError(0xdeadbeef);
2965     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2966     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2967      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2968     CryptMsgClose(msg);
2969
2970     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2971     /* A signed message succeeds, .. */
2972     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2973      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2974     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2975     ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2976     /* the signer index can be retrieved, .. */
2977     signerIndex = 0xdeadbeef;
2978     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2979     ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2980     ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
2981     /* as can the signer cert. */
2982     signer = (PCCERT_CONTEXT)0xdeadbeef;
2983     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2984     ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2985     ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
2986      "expected a valid signer\n");
2987     if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
2988         CertFreeCertificateContext(signer);
2989     /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
2990      */
2991     signerIndex = 0xdeadbeef;
2992     SetLastError(0xdeadbeef);
2993     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
2994      NULL, &signerIndex);
2995     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
2996      "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
2997     /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
2998      * message signer not to be found.
2999      */
3000     SetLastError(0xdeadbeef);
3001     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3002      NULL, NULL);
3003     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3004      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3005     /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3006      * the message signer not to be found.
3007      */
3008     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3009      CERT_STORE_CREATE_NEW_FLAG, NULL);
3010     SetLastError(0xdeadbeef);
3011     ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3012      NULL, NULL);
3013     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3014      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3015     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3016      v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3017      CERT_STORE_ADD_ALWAYS, NULL);
3018     ok(ret, "CertAddEncodedCertificateToStore failed: 0x%08x\n",
3019      GetLastError());
3020     /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3021      * the signer succeeds.
3022      */
3023     SetLastError(0xdeadbeef);
3024     ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3025      NULL, NULL);
3026     ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3027     CertCloseStore(store, 0);
3028     CryptMsgClose(msg);
3029 }
3030
3031 START_TEST(msg)
3032 {
3033     init_function_pointers();
3034     have_nt = detect_nt();
3035
3036     /* Basic parameter checking tests */
3037     test_msg_open_to_encode();
3038     test_msg_open_to_decode();
3039     test_msg_get_param();
3040     test_msg_close();
3041     test_msg_control();
3042
3043     /* Message-type specific tests */
3044     test_data_msg();
3045     test_hash_msg();
3046     test_signed_msg();
3047     test_decode_msg();
3048
3049     test_msg_get_and_verify_signer();
3050 }